

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=&#34;auto&#34;>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/blog/img/favicon.png">
  <link rel="icon" href="/blog/img/favicon.jpg">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="">
  <meta name="author" content="John Doe">
  <meta name="keywords" content="">
  
  <title>Node.js笔记 - ITaylorfan的小站</title>

  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/blog/lib/hint/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@10.7.2/styles/github-gist.min.css" />
    
  

  
    <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" />
  



<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">


<link  rel="stylesheet" href="/blog/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"itaylorfan.gitee.io","root":"/blog/","version":"1.8.11","typing":{"enable":true,"typeSpeed":70,"cursorChar":"❤","loop":false},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"right","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null}},"search_path":"/local-search.xml"};
  </script>
  <script  src="/blog/js/utils.js" ></script>
  <script  src="/blog/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 5.4.0"></head>


<body>
  <header style="height: 85vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/blog/">&nbsp;<strong>ITaylorfan</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" data-toggle="modal" data-target="#modalSearch">&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;</a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('/blog/img/TS8-10-9.jpg') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="Node.js笔记">
              
            </span>

            
              <div class="mt-3">
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2021-11-16 08:38" pubdate>
        2021年11月16日 早上
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      14.7k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      193
       分钟
    </span>
  

  
  
</div>

            
          </div>

          
            <div class="scroll-down-bar">
              <i class="iconfont icon-arrowdown"></i>
            </div>
          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">Node.js笔记</h1>
            
            <div class="markdown-body">
              <h2 id="1-介绍与安装"><a href="#1-介绍与安装" class="headerlink" title="1.介绍与安装"></a>1.介绍与安装</h2><h3 id="关于Node-js"><a href="#关于Node-js" class="headerlink" title="关于Node.js"></a>关于Node.js</h3><p>node.js其实可以理解为ECMAScript在服务器上面的运行环境。</p>
<p>我们以前在学习javascript总有一个概念，javascript运行在浏览器的网页里面，它必须依托于网页存在，没有网页就没有它。但是后期人们将javascript 运行在浏览器上面的一个环境<code>chrome V8</code>移植到了服务器上面，这样就可以保证我们的js代码能够在本地的服务器上面运行了，而不依赖于浏览器与网页</p>
<p>node.js它只是一个运行平台，不关于任何标准，只要是javascript语言，我都可以在上面运行</p>
<h3 id="什么前端需要学Node-js"><a href="#什么前端需要学Node-js" class="headerlink" title="什么前端需要学Node.js"></a>什么前端需要学Node.js</h3><p>按照以前的开发思维，前端是不需要学习后端的具体知识，只要掌握一些基本的后端原理即可。但是现在的主流开发方式上面已经趋向于前后端分离式开发，而在这种开发模式下面，后端不负责前的问题，而前端反而需要掌握一些后端的知识，如果数据建模，数据库设计，SQL语句，以及http请求原理，cdn优化等一系列后端知识</p>
<p>在之前的时候后端知识我们都是以<code>php</code>为方式来学习的，但是毕竟<code>php</code>是一门新的编程语言，它的接受难度与学习成本都比较大，这样做不合适。nodejs推出了以后它完全可以替代<code>php</code>语言，同时还可以在我们的JS上面做很多的扩展，我们有很多的插件都是可以运行在nodejs上面的，并且它没有学习一门新的语言，<strong>我们之前JS是可以完全运行在上面的</strong></p>
<p>node.js还具备一些先天性的优点</p>
<ol>
<li>非阻涉的IO</li>
<li>使用事件驱动</li>
<li>天生的高并发处理能力</li>
<li>单线程的执行</li>
</ol>
<p>node.js它只是一个运行平台，在这个平台上面运行是javascript语句，但是一般情况它，它的兼容性非常强（nodejs是装在服务器上面的，服务器的环境是由我们来决定的，不是由客户的浏览器来决定的，所以我们可以实时更新自己服务器的运行环境）</p>
<p>只是因为没有兼容性，所以我们在nodejs上面运行的js代码可以是更高级版本的JS代码。这个时候我们的<code>ECMAScript6</code>就可以直接在上面运行（包括后面的ES7,ES8）</p>
<p><strong>node.js里面只有ECMAScript，没有DOM，也没有BOM</strong></p>
<h3 id="安装Node-js"><a href="#安装Node-js" class="headerlink" title="安装Node.js"></a>安装Node.js</h3><p>下载地址：<a target="_blank" rel="noopener" href="http://nodejs.cn/">Node.js 中文网 (nodejs.cn)</a></p>
<p><img src="https://pic.imgdb.cn/item/6166cd502ab3f51d91b95472.jpg" srcset="/blog/img/loading.gif" lazyload alt="img"></p>
<h4 id="1、双击下载好的软件"><a href="#1、双击下载好的软件" class="headerlink" title="1、双击下载好的软件"></a>1、双击下载好的软件</h4><p><img src="https://pic.imgdb.cn/item/6166cd5e2ab3f51d91b96800.png" srcset="/blog/img/loading.gif" lazyload alt="img"></p>
<h4 id="2、点击Next"><a href="#2、点击Next" class="headerlink" title="2、点击Next"></a>2、点击Next</h4><p><img src="https://pic.imgdb.cn/item/6166cd6c2ab3f51d91b97aa7.png" srcset="/blog/img/loading.gif" lazyload alt="img"></p>
<h4 id="3、选中后点击Next"><a href="#3、选中后点击Next" class="headerlink" title="3、选中后点击Next"></a>3、选中后点击Next</h4><p><img src="https://pic.imgdb.cn/item/6166cd792ab3f51d91b98bc8.png" srcset="/blog/img/loading.gif" lazyload alt="img"></p>
<h4 id="4、修改安装目录后点击Next"><a href="#4、修改安装目录后点击Next" class="headerlink" title="4、修改安装目录后点击Next"></a>4、修改安装目录后点击Next</h4><p>（建议安装在非C盘的其他盘）</p>
<p><img src="https://pic.imgdb.cn/item/6166cd8a2ab3f51d91b9a4f6.png" srcset="/blog/img/loading.gif" lazyload alt="img"></p>
<h4 id="5、默认，直接点击Next"><a href="#5、默认，直接点击Next" class="headerlink" title="5、默认，直接点击Next"></a>5、默认，直接点击Next</h4><p><img src="https://pic.imgdb.cn/item/6166cd9b2ab3f51d91b9be32.png" srcset="/blog/img/loading.gif" lazyload alt="img"></p>
<h4 id="6、直接Next"><a href="#6、直接Next" class="headerlink" title="6、直接Next"></a>6、直接Next</h4><p><img src="https://pic.imgdb.cn/item/6166cdb32ab3f51d91b9db7a.png" srcset="/blog/img/loading.gif" lazyload alt="img"></p>
<h4 id="7、点击Install进行安装，等待安装完成"><a href="#7、点击Install进行安装，等待安装完成" class="headerlink" title="7、点击Install进行安装，等待安装完成"></a>7、点击Install进行安装，等待安装完成</h4><p><img src="https://pic.imgdb.cn/item/6166cdca2ab3f51d91b9fc32.png" srcset="/blog/img/loading.gif" lazyload alt="img"></p>
<p><img src="https://pic.imgdb.cn/item/6166cdd72ab3f51d91ba0e64.png" srcset="/blog/img/loading.gif" lazyload alt="img"></p>
<h4 id="8、安装完成，点击Finish"><a href="#8、安装完成，点击Finish" class="headerlink" title="8、安装完成，点击Finish"></a>8、安装完成，点击Finish</h4><p><img src="https://pic.imgdb.cn/item/6166cde32ab3f51d91ba205a.png" srcset="/blog/img/loading.gif" lazyload alt="img"></p>
<h4 id="9、验证是否安装成功"><a href="#9、验证是否安装成功" class="headerlink" title="9、验证是否安装成功"></a>9、验证是否安装成功</h4><p>由于是通过msi格式安装的，所以启动路径会自动添加进path中，可以通过cmd直接掉用</p>
<ul>
<li><p>win+r：在弹窗中输入cmd打开cmd窗口</p>
</li>
<li><p>在cmd窗口中输入node -v，出现如下版本信息及安装成功。</p>
</li>
</ul>
<p><img src="https://pic.imgdb.cn/item/6166cde32ab3f51d91ba205a.png" srcset="/blog/img/loading.gif" lazyload alt="image-20210513095253468"></p>
<hr>
<h2 id="2-Node基础"><a href="#2-Node基础" class="headerlink" title="2.Node基础"></a>2.Node基础</h2><h3 id="node-js的运行"><a href="#node-js的运行" class="headerlink" title="node.js的运行"></a>node.js的运行</h3><p>当我们装好了node.js的运行环境以后，我们可以在控制台输入命令<code>node -v</code>查看代码，如果这个时候可以正学中的显示版本号，那么，则安装成功</p>
<p>安装成功以后，我们如果要运行node.js，则非常简单，只需要执行一个命令即可</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ node 文件名.js<br></code></pre></td></tr></table></figure>

<p>如</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ node 01.js<br></code></pre></td></tr></table></figure>

<p>在node.js里面不能运行<code>DOM</code>与<code>BOM</code>，只能运行<code>ECMAScript</code></p>
<p><strong>01.js</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;hello world&quot;</span>);<br><span class="hljs-built_in">window</span>.alert(<span class="hljs-string">&quot;hello&quot;</span>);			<span class="hljs-comment">//window是浏览器BOM里面的东西，不能在node里面使用</span><br></code></pre></td></tr></table></figure>

<p>在以<code>node 01.js</code>去很执行的时候，这个时候就会报错</p>
<hr>
<h3 id="CommonJS模块化"><a href="#CommonJS模块化" class="headerlink" title="CommonJS模块化"></a>CommonJS模块化</h3><p>在之前学习ES6的时候，我们学习了ESModule的模块化规范，现在我们再来复习一下</p>
<pre><code class=" mermaid">graph TD
A[模块化]--&gt;B[过时标准]
A--&gt;C[现行标准]
B--&gt;B1(AMD规范)
B--&gt;B2(CMD规范)
C--&gt;|浏览器及通用EMCA|C1[ESModule规范]
C--&gt;|node.js平台|C2[CommonJS规范]
</code></pre>

<p>在上面的图里面，我们可以看到，<code>ES6</code>及通用的ECMA使用的都是<code>ESModule</code>这一种模块化，目前这也是一个主流，基本上90%以上都是使用这一个模块化，但是唯独<code>node.js</code>使用的是<code>CommonJS</code>模块化</p>
<ol>
<li><p>在<code>ESModule</code>里面，我们使用<code>export</code>导出，使用<code>import</code>导入</p>
</li>
<li><p>在<code>CommonJS</code>里面，我们使用<code>module.exports</code>导出 ，使用<code>require</code>导入</p>
<table>
<thead>
<tr>
<th></th>
<th>导出</th>
<th>导入</th>
</tr>
</thead>
<tbody><tr>
<td><code>ESModule</code>规范</td>
<td><code>export</code>关键字</td>
<td><code>import</code>关键字</td>
</tr>
<tr>
<td><code>CommonJS</code>规范</td>
<td><code>module.exports</code></td>
<td><code>require()</code>方法</td>
</tr>
</tbody></table>
</li>
</ol>
<p>现在先看下面的代码</p>
<p><strong>Person.js文件</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>&#123;<br>    <span class="hljs-function"><span class="hljs-title">constructor</span>(<span class="hljs-params">userName, sex</span>)</span> &#123;<br>        <span class="hljs-built_in">this</span>.userName = userName;<br>        <span class="hljs-built_in">this</span>.sex = sex;<br>    &#125;<br>    <span class="hljs-function"><span class="hljs-title">sayHello</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`大家好，我叫<span class="hljs-subst">$&#123;<span class="hljs-built_in">this</span>.userName&#125;</span>，我的性别是<span class="hljs-subst">$&#123;<span class="hljs-built_in">this</span>.sex&#125;</span>`</span>);<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">// export default Person;</span><br><span class="hljs-built_in">module</span>.exports = Person;<br></code></pre></td></tr></table></figure>

<p><strong>Student.js文件</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// import Person from &quot;./Person.js&quot;;</span><br><span class="hljs-keyword">const</span> Person =  <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;./Person.js&quot;</span>);<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Studnet</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Person</span> </span>&#123;<br>    <span class="hljs-function"><span class="hljs-title">constructor</span>(<span class="hljs-params">userName, sex, age, sid</span>)</span> &#123;<br>        <span class="hljs-built_in">super</span>(userName, sex);<br>        <span class="hljs-built_in">this</span>.age = age;<br>        <span class="hljs-built_in">this</span>.sid = sid;<br>    &#125;<br>&#125;<br><span class="hljs-keyword">let</span> s1 = <span class="hljs-keyword">new</span> Studnet(<span class="hljs-string">&quot;张珊&quot;</span>, <span class="hljs-string">&quot;女&quot;</span>, <span class="hljs-number">18</span>, <span class="hljs-string">&quot;1001&quot;</span>);<br>s1.sayHello();<br></code></pre></td></tr></table></figure>

<p>当我们在去执行<code>node Student.js</code>的时候，这个时候就不会报了，因为我们使用的是node.js里面的模块化规范</p>
<h3 id="CommonJS的模块导入"><a href="#CommonJS的模块导入" class="headerlink" title="CommonJS的模块导入"></a>CommonJS的模块导入</h3><p>在上面的章节我们已经实初步的了解了<code>commonjs</code>的相关知识 ，我们也知道了导入使用<code>require()</code>，现在细究一下</p>
<p><img src="https://pic.imgdb.cn/item/6166ce9e2ab3f51d91bb224c.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013102944766"></p>
<p>当我们需要拿一个文件过来的时候，我们直接使用<code>require</code>就可以了</p>
<p><img src="https://pic.imgdb.cn/item/6166ceb22ab3f51d91bb3e40.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013103052641"></p>
<p>当我们导入了多次的时候，我们也了发现，最终a.js的代码也只会执行一次</p>
<p><strong>requre()方法导入一个模块以后，它会把这个模块缓存下来，下次再去导入，则直接从缓存里面拿</strong>，在上面的代码里面，表现看代码是导入了6次，其实只是第1次的时候导入了，剩下的5次都是从缓存里面拿的</p>
<h3 id="CommonJS缓存"><a href="#CommonJS缓存" class="headerlink" title="CommonJS缓存"></a>CommonJS缓存</h3><p>如果希望某一个模块不放在缓存里面，我们可以在这个模块的最后添加如下代码</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//删除缓存</span><br><span class="hljs-keyword">delete</span> <span class="hljs-built_in">require</span>.cache[<span class="hljs-built_in">module</span>.filename];<br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/6166cec12ab3f51d91bb50d7.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013103538999"></p>
<p>这个时候我们再去执行<code>node b.js</code>的时候，<code>a.js</code>的代码就没有缓存 ，它就会导入6次，那么<code>a.js</code>的代码就会执行6次</p>
<h3 id="CommonJS的模块导出"><a href="#CommonJS的模块导出" class="headerlink" title="CommonJS的模块导出"></a>CommonJS的模块导出</h3><p>导入与导出应该是一对，所以在nodejs里面如果要导出我们可以使用下面的两种方式</p>
<ol>
<li><code>module.exports</code>直接导出</li>
<li><code>exports</code>指针导出</li>
</ol>
<p><img src="https://pic.imgdb.cn/item/6166ced62ab3f51d91bb6d76.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013104628199"></p>
<p>上图代码就是最基本的导入与导出</p>
<p>在<code>CommonJS</code>的模块化规范里面，每个文件都会有个<strong>专门用于导出</strong>的属性叫<code>module.exports</code>,我们require的时候其实就是导入了<code>module.exports</code>这个东西</p>
<h4 id="module-exports"><a href="#module-exports" class="headerlink" title="module.exports"></a>module.exports</h4><p>在每个文件里面，都有一个专门用于负责导出的对象，这个对象叫<code>module.exports</code>，如果我们直接打印<code>module.exports</code>我们会看到它是一个空的对象<code>&#123;&#125;</code></p>
<p><img src="https://pic.imgdb.cn/item/6166ceef2ab3f51d91bb92a4.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013105123385"></p>
<p>如果我们需要同时导出多个变量的时候，我们可以把这个变量封装成对象，然后再导出，这样在另一个文件里面就可以使用<code>require</code>导入这个对象，然后再取值</p>
<p>当然我们也可以进一步演变成一种最常用的方式，如下，使用ES6的解构来进行</p>
<p><img src="https://pic.imgdb.cn/item/6166ceff2ab3f51d91bbad2c.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013105423564"></p>
<h4 id="exports"><a href="#exports" class="headerlink" title="exports"></a>exports</h4><p>在CommonJS的模块化规范里面，真正负责导出的是<code>module.exports</code>，但是<strong>还有一个指针默认指向了</strong>这个<code>module.exports</code>，我们现在通过内存图来看看</p>
<p><img src="https://pic.imgdb.cn/item/6166cf2a2ab3f51d91bbea2e.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013110539916"></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">module</span>.exports === <span class="hljs-built_in">exports</span>);			<span class="hljs-comment">//true</span><br></code></pre></td></tr></table></figure>

<p><strong>场景一</strong></p>
<p><img src="https://pic.imgdb.cn/item/6166cf482ab3f51d91bc1452.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013110923516"></p>
<p>在上面的代码里面，既有<code>module.exports</code>导出 ，又有<code>exports</code>导出 ，则b.js里面导入的到底是谁？</p>
<p><img src="https://pic.imgdb.cn/item/6166cf482ab3f51d91bc1452.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013111225353"></p>
<p>始终都要记住一句话，真正导入的是<code>module.exports</code>的东西，所以这个时候b.js导入的其实是<code>userName</code>，结果就是“张三”</p>
<p><strong>场景二</strong></p>
<p><img src="https://pic.imgdb.cn/item/6166cf482ab3f51d91bc1452.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013111608627"></p>
<p>在上面的代码里面，我们没有直接改变<code>module.exports</code>及<code>exports</code>在栈里的地址，现在再看内存图</p>
<p><img src="https://pic.imgdb.cn/item/6166cf852ab3f51d91bc6ce8.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013111745011"></p>
<p>真正负责导出的还是<code>module.exports</code>，我们现在这个导出的对象上面已经有了两个属性了</p>
<p><strong>场景三</strong></p>
<p><img src="https://pic.imgdb.cn/item/6166cf9c2ab3f51d91bc8e79.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013112144595"></p>
<p><img src="https://pic.imgdb.cn/item/6166cfb72ab3f51d91bcb62c.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013112319478"></p>
<p>这个时候的内存图与上面的内存图是一样效果，因为我们并没有改变<code>exports</code>与<code>module.exports</code>的栈的地址</p>
<p><strong>场景四</strong></p>
<p><img src="https://pic.imgdb.cn/item/6166cfcb2ab3f51d91bcd4ae.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013112435439"></p>
<p><img src="https://pic.imgdb.cn/item/6166cfdb2ab3f51d91bcea91.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211013112550658"></p>
<p>还是一句话，真正负责导出的是<code>module.exports</code>，所以b.js得到的就是<code>&#123;hobby:&quot;看书&quot;&#125;</code></p>
<p>为了避免同学们产生歧义不好理解，我们当前阶段统一使用<code>module.exports</code></p>
<hr>
<h3 id="node-js内置模块"><a href="#node-js内置模块" class="headerlink" title="node.js内置模块"></a>node.js内置模块</h3><p>node.js做为一个运行平台，它有很多内置的模块 ，其中我们当前阶段主要使用的模块有以下几个</p>
<ol>
<li><code>path</code>路径模块 </li>
<li><code>fs</code>文件模块</li>
<li><code>os</code>系统模块</li>
<li><code>http</code>网络请求模块</li>
</ol>
<h4 id="path模块"><a href="#path模块" class="headerlink" title="path模块"></a>path模块</h4><p>这个模块叫路径模块 ，因为<code>node.js</code>是运行在本地电脑，所以每个人运行JS文件的路径是不一样的，我们后期就需要通过这个模块去控制路径的问题</p>
<p>其中有<code>node.js</code>里面有两个变量是固定存在的</p>
<ol>
<li><code>__dirname</code>代表当前JS运行的目录路径</li>
<li><code>__filename</code>代表当前JS运行的文件路径 </li>
</ol>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-built_in">console</span>.log(__dirname);<br><span class="hljs-comment">//D:\杨标的工作文件\班级教学笔记\H2103\1013\code\nodejs_05</span><br><br><span class="hljs-built_in">console</span>.log(__filename);<br><span class="hljs-comment">//D:\杨标的工作文件\班级教学笔记\H2103\1013\code\nodejs_05\01.js</span><br></code></pre></td></tr></table></figure>

<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;path&quot;</span>);<br></code></pre></td></tr></table></figure>

<ol>
<li><code>path.join()</code>方法，该方法用于拼接路径</li>
<li><code>path.extname()</code>方法，该方法获取一个路径后缀名</li>
<li><code>path.isAbsolute()</code>方法，判断某一个路径是否是绝对路径 </li>
<li><code>path.resolve()</code>方法，该方法可以将一个相对路径转换成绝对路径</li>
</ol>
<h4 id="FS模块"><a href="#FS模块" class="headerlink" title="FS模块"></a>FS模块</h4><p>这个模块也是nodejs的内置模块 ，有了路径我们就可以操作文件或文件夹</p>
<blockquote>
<p>FS的全称有两咱意思，第一种理解为<code>File System</code>文件系统，第二种理解为<code>File Stream</code>文件流</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;fs&quot;</span>);<br></code></pre></td></tr></table></figure>

<ol>
<li><p><code>fs.existsSync()</code>方法，判断某一个文件夹或文件是否存在</p>
</li>
<li><p><code>fs.rmdirSync()</code>方法，删除一个文件夹。如果这个文件夹不为空，则不能删除</p>
</li>
<li><p><code>fs.unlinkSync()</code>方法，删除某一个文件</p>
</li>
<li><p><code>fs.copyFileSync()</code>方法，复制一个文件</p>
</li>
<li><p><code>fs.renameSync()</code>方法，对一个文件重命名</p>
<p><code>fs.renameSync()</code>方法的本意是文件重命名，但是如果这个文件重命名的时候不在同一个文件夹就相于剪切操作</p>
</li>
<li><p><code>fs.mkdirSync()</code>创建一个文件夹</p>
</li>
<li><p><code>fs.readdirSync()</code>读取一个文件夹的信息，它会返回一个数组，这个数组里面包含所有的子级信息，有文件夹的，也有文件的</p>
</li>
<li><p><code>fs.statSync()</code>方法，返回某一个路径的信息，信息如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs javascript">Stats &#123;<br>  <span class="hljs-attr">dev</span>: <span class="hljs-number">44114680</span>,<br>  <span class="hljs-attr">mode</span>: <span class="hljs-number">16822</span>,<br>  <span class="hljs-attr">nlink</span>: <span class="hljs-number">1</span>,<br>  <span class="hljs-attr">uid</span>: <span class="hljs-number">0</span>,<br>  <span class="hljs-attr">gid</span>: <span class="hljs-number">0</span>,<br>  <span class="hljs-attr">rdev</span>: <span class="hljs-number">0</span>,<br>  <span class="hljs-attr">blksize</span>: <span class="hljs-number">4096</span>,<br>  <span class="hljs-attr">ino</span>: <span class="hljs-number">562949953923999</span>,<br>  <span class="hljs-attr">size</span>: <span class="hljs-number">0</span>,<br>  <span class="hljs-attr">blocks</span>: <span class="hljs-number">0</span>,<br>  <span class="hljs-attr">atimeMs</span>: <span class="hljs-number">1634107627178.0852</span>,<br>  <span class="hljs-attr">mtimeMs</span>: <span class="hljs-number">1634107567559.8716</span>,	  <span class="hljs-comment">//文件修改的时间</span><br>  <span class="hljs-attr">ctimeMs</span>: <span class="hljs-number">1634107567559.8716</span>,    <span class="hljs-comment">//文件创建的时间，对应ctime，也就是birthtime</span><br>  <span class="hljs-attr">birthtimeMs</span>: <span class="hljs-number">1634107020140.7776</span>,<br>  <span class="hljs-attr">atime</span>: <span class="hljs-number">2021</span>-<span class="hljs-number">10</span>-13T06:<span class="hljs-number">47</span>:<span class="hljs-number">07</span>.178Z,<br>  <span class="hljs-attr">mtime</span>: <span class="hljs-number">2021</span>-<span class="hljs-number">10</span>-13T06:<span class="hljs-number">46</span>:<span class="hljs-number">07</span>.560Z,<br>  <span class="hljs-attr">ctime</span>: <span class="hljs-number">2021</span>-<span class="hljs-number">10</span>-13T06:<span class="hljs-number">46</span>:<span class="hljs-number">07</span>.560Z,<br>  <span class="hljs-attr">birthtime</span>: <span class="hljs-number">2021</span>-<span class="hljs-number">10</span>-13T06:<span class="hljs-number">37</span>:<span class="hljs-number">00</span>.141Z<br>&#125;<br></code></pre></td></tr></table></figure>

<p>在读取的结果里面有两个方法一定要注意</p>
<ul>
<li><code>isDirectory()</code>用于判定当前路径是否是一个文件夹</li>
<li><code>isFile()</code>用于判定当前路径是否是一个文件</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> p1 = path.join(__dirname, <span class="hljs-string">&quot;./abc&quot;</span>);<br><span class="hljs-keyword">if</span> (fs.existsSync(p1)) &#123;<br>    <span class="hljs-comment">//读取这个路径的信息</span><br>    <span class="hljs-keyword">let</span> p1Info = fs.statSync(p1);<br>    <span class="hljs-built_in">console</span>.log(p1Info.isDirectory());      <span class="hljs-comment">//true</span><br>    <span class="hljs-built_in">console</span>.log(p1Info.isFile());           <span class="hljs-comment">//false</span><br>&#125;<br><br><span class="hljs-keyword">let</span> p2 = path.join(__dirname, <span class="hljs-string">&quot;./01.js&quot;</span>);<br><span class="hljs-keyword">if</span> (fs.existsSync(p2)) &#123;<br>    <span class="hljs-keyword">let</span> p2Info = fs.statSync(p2);<br>    <span class="hljs-built_in">console</span>.log(p2Info.isFile());           <span class="hljs-comment">//true</span><br>    <span class="hljs-built_in">console</span>.log(p2Info.isDirectory());      <span class="hljs-comment">//false</span><br>&#125;<br><br></code></pre></td></tr></table></figure>
</li>
<li><p><code>fs.readFileSync()</code>方法，该方法是读取某一个文件的内容</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;path&quot;</span>);<br><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;fs&quot;</span>);<br><br><span class="hljs-keyword">let</span> p1 = path.join(__dirname, <span class="hljs-string">&quot;./item33.png&quot;</span>);<br><span class="hljs-comment">/*</span><br><span class="hljs-comment">if (fs.existsSync(p1)) &#123;</span><br><span class="hljs-comment">    let p1Info = fs.statSync(p1);</span><br><span class="hljs-comment">    if (p1Info.isFile()) &#123;</span><br><span class="hljs-comment">        //读文件</span><br><span class="hljs-comment">    &#125;</span><br><span class="hljs-comment">&#125;</span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">if</span> (fs.existsSync(p1) &amp;&amp; fs.statSync(p1).isFile()) &#123;<br>    <span class="hljs-keyword">let</span> result = fs.readFileSync(p1);<br>    <span class="hljs-built_in">console</span>.log(result.toString(<span class="hljs-string">&quot;base64&quot;</span>));<br>&#125;<br></code></pre></td></tr></table></figure>
</li>
<li><p><code>fs.writeFileSync()</code>方法，该方法是将一个内容写入到文件里面</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> *  当前目录下面的base.txt里面记录了一串base64的字符串</span><br><span class="hljs-comment"> *  1.读取base.txt这个文件得到这个base64字符串</span><br><span class="hljs-comment"> *  2.在当前目录下面写入一个biaogege.png的图片，使用base64写入</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;path&quot;</span>);<br><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;fs&quot;</span>);<br><br><span class="hljs-comment">//第一步：先构造base.txt的路径 </span><br><span class="hljs-keyword">let</span> p1 = path.join(__dirname, <span class="hljs-string">&quot;./base.txt&quot;</span>);<br><span class="hljs-comment">//第二步：构造要保存的图片的路径</span><br><span class="hljs-keyword">let</span> p2 = path.join(__dirname, <span class="hljs-string">&quot;./biaogege.png&quot;</span>);<br><span class="hljs-comment">//第三步：再读取之前，我们一定要判断当前的路径是否存在，并且一定是一个文件</span><br><span class="hljs-keyword">if</span> (fs.existsSync(p1) &amp;&amp; fs.statSync(p1).isFile()) &#123;<br>    <span class="hljs-keyword">let</span> result = fs.readFileSync(p1);  <span class="hljs-comment">//Buffer</span><br>    <span class="hljs-comment">//第四步：将读取的Buffer转换成字符串</span><br>    <span class="hljs-keyword">let</span> base64Str = result.toString();<br>    <span class="hljs-comment">//第五步：将这个base64格式的字符串写入到文件</span><br>    fs.writeFileSync(p2, base64Str, &#123; <span class="hljs-attr">encoding</span>: <span class="hljs-string">&quot;base64&quot;</span> &#125;);<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;写入成功&quot;</span>);<br>&#125;<br></code></pre></td></tr></table></figure>

</li>
</ol>
<h4 id="OS模块"><a href="#OS模块" class="headerlink" title="OS模块"></a>OS模块</h4><p>这个模块是用于获取系统信息的模块</p>
<ol>
<li><code>os.freemem()</code>方法，该方法用于获取当前系统的空闲内存</li>
<li><code>os.totalmem()</code>方法，该方法用于获取当前系统的总内存</li>
<li><code>os.cpus()</code>方法，该方法用于获取当前的CPU信息</li>
<li><code>os.networkInterfaces()</code>方法，用于获取当前前系统的网络网卡信息</li>
<li><code>os.platform()</code>方法，用于获取当前系统平台，如果是<code>windows</code>则显示<code>win32</code>，还有<code>linux</code>和<code>mac</code>的情况</li>
<li><code>os.hostname()</code>方法，用于获取当前电脑的电脑名称（主机名称）</li>
<li><code>os.tmpdir()</code> 方法，用于获取当前电脑上面的临时目录，这个目录后期会大量使用， 因为它可以存放我们的临时文件</li>
<li><code>os.homedir()</code>方法，用于获取当前用户的主路径</li>
</ol>
<hr>
<h2 id="3-npm工具"><a href="#3-npm工具" class="headerlink" title="3.npm工具"></a>3.npm工具</h2><h3 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h3><p>之前我们在学习的时候已经学习过nodejs的内置模块 了，其实node.js还有大量的第三方模块提供给我们使用，例如数据请求的<code>axios</code>，抓包分析的<code>cheerio</code>，例如数据操作的<code>mysql</code>，例如实现MVC开发了<code>express</code>或<code>KOA</code>等</p>
<p>第三模块有一个专门的管理工具叫<code>npm</code>，在安装node.js的时候已经自带这个工具了，如下图所示</p>
<img src="https://pic.imgdb.cn/item/6166cd9b2ab3f51d91b9be32.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211014095041348" style="zoom:50%;" />

<ol>
<li><code>npm</code>理解为<code>network package manager</code>网络包管理工具</li>
<li><code>npm</code>理解为<code>nodejs package manager</code> node.js的包管理工具</li>
</ol>
<blockquote>
<p>nodejs是以文件夹为单位来管理项目的，所以请同学们在学习nodejs的时候尽量不要在vscode里面同时打开多个项目</p>
</blockquote>
<h3 id="npm初始化"><a href="#npm初始化" class="headerlink" title="npm初始化"></a>npm初始化</h3><p>nodejs是以文件夹为单位来管理自己的项目，如果当前的文本夹是一个nodejs的项目则应该要进行初始化，初始化的命令如下</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm init<br></code></pre></td></tr></table></figure>

<p>当执行完一系列的操作以后，我们就可以看到在当前的文件夹下面会多出一个<code>package.json</code>的文件，这个文件记录了你初始化的时候一些信息</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs javascript">&#123;<br>  <span class="hljs-string">&quot;name&quot;</span>: <span class="hljs-string">&quot;101402&quot;</span>,<br>  <span class="hljs-string">&quot;version&quot;</span>: <span class="hljs-string">&quot;1.0.0&quot;</span>,<br>  <span class="hljs-string">&quot;description&quot;</span>: <span class="hljs-string">&quot;标哥哥的第一个node.js项目&quot;</span>,<br>  <span class="hljs-string">&quot;main&quot;</span>: <span class="hljs-string">&quot;index.js&quot;</span>,<br>  <span class="hljs-string">&quot;scripts&quot;</span>: &#123;<br>    <span class="hljs-string">&quot;test&quot;</span>: <span class="hljs-string">&quot;echo \&quot;Error: no test specified\&quot; &amp;&amp; exit 1&quot;</span><br>  &#125;,<br>  <span class="hljs-string">&quot;keywords&quot;</span>: [<br>    <span class="hljs-string">&quot;标哥&quot;</span>,<br>    <span class="hljs-string">&quot;nodejs第一步&quot;</span><br>  ],<br>  <span class="hljs-string">&quot;author&quot;</span>: <span class="hljs-string">&quot;标哥哥&quot;</span>,<br>  <span class="hljs-string">&quot;license&quot;</span>: <span class="hljs-string">&quot;MIT&quot;</span><br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="package-json介绍"><a href="#package-json介绍" class="headerlink" title="package.json介绍"></a>package.json介绍</h3><ul>
<li> <code>name</code>代表的是当前包的名称，也就是node.js项目的名称</li>
<li> <code>version</code>代表的是版本</li>
<li> <code>description</code>描述当前项目的信息</li>
<li> <code>main.js</code>代表整个node.js的项目应该从哪个地方文件开始启动，我们一般会使用<code>app.js</code>，<code>main.js</code>或<code>index.js</code>来完成</li>
<li> <code>scripts</code>脚本配置，后期可以在项目当中配置这个脚本以实现项目的快速启动</li>
<li> <code>keywords</code>关键字设置</li>
<li> <code>author</code>设置作者</li>
<li> <code>license</code>版权</li>
</ul>
<h3 id="远端仓库npmjs"><a href="#远端仓库npmjs" class="headerlink" title="远端仓库npmjs"></a>远端仓库npmjs</h3><p>有一个网站上面保留了我们所有的第三方模块 ，这个网站就是</p>
<p><code>[npm (npmjs.com)](https://www.npmjs.com/)</code></p>
<p><img src="https://pic.imgdb.cn/item/61681c902ab3f51d916fcf1f.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211014111011275"></p>
<p>我们可以根据自己的需求来查找相关包的信息</p>
<h3 id="npm-info查看包的信息"><a href="#npm-info查看包的信息" class="headerlink" title="npm info查看包的信息"></a>npm info查看包的信息</h3><p>我们可以直接通过<code>npmjs</code>的网站去查看包的信息，也可以通过自带的控制台的命令查看包的信息</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm info 包名称<br></code></pre></td></tr></table></figure>

<p>如我们输入如下命令</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm info bootstrap<br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/61681cd52ab3f51d91704d3b.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211014112012762"></p>
<h3 id="npm-install安装包"><a href="#npm-install安装包" class="headerlink" title="npm install安装包"></a>npm install安装包</h3><p>当我们需要去下载一个远程仓库的第三方包的时候，我们可以直接使用<code>npm install</code>的命令，</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install bootstrap<br></code></pre></td></tr></table></figure>

<p>上面的命令是下载bootstrap的包</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install jquery<br></code></pre></td></tr></table></figure>

<p>这就下载了jQuery的包</p>
<p><img src="https://pic.imgdb.cn/item/61681cfb2ab3f51d9170909f.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211014112234508"></p>
<p>当下载完成以后，所以的包都会在<code>node_modules</code>的文件夹里面，这个文件夹里面存放了所有的第三方模块信息</p>
<h3 id="–save记录安装信息"><a href="#–save记录安装信息" class="headerlink" title="–save记录安装信息"></a>–save记录安装信息</h3><p>当我们在使用<code>npm install</code>去安装第三方包的时候，我们会直接把下载下来，放在<code>node_modules</code>文件夹里面，但是有个问题，如果后期项目变大了，使用了第多第三方依赖的时候，这个时候我们就不知道自己下载了多少包</p>
<p>所以每一次远程开发包的下载安装信息我们都要记录下载</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install bootstrap --save<br></code></pre></td></tr></table></figure>

<p>我们可以看到在上面的安装包命令里面后面添加了一个<code>--save</code>，这个代表本次的安装信息记录在当前项目的配置文件<code>package.json</code>里面，这个代表生产依赖</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install jquery --save-dev<br></code></pre></td></tr></table></figure>

<p>这个时候后面的命令变成了<code>--save-dev</code>，这个代表开发依赖</p>
<p>当执行完上面的命令以后，我们可以看到<code>package.json</code>的文件变成了如下的样子</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs javascript">&#123;<br>  <span class="hljs-string">&quot;name&quot;</span>: <span class="hljs-string">&quot;101402&quot;</span>,<br>  <span class="hljs-string">&quot;version&quot;</span>: <span class="hljs-string">&quot;1.0.0&quot;</span>,<br>  <span class="hljs-string">&quot;description&quot;</span>: <span class="hljs-string">&quot;标哥哥的第一个node.js项目&quot;</span>,<br>  <span class="hljs-string">&quot;main&quot;</span>: <span class="hljs-string">&quot;index.js&quot;</span>,<br>  <span class="hljs-string">&quot;scripts&quot;</span>: &#123;<br>    <span class="hljs-string">&quot;test&quot;</span>: <span class="hljs-string">&quot;echo \&quot;Error: no test specified\&quot; &amp;&amp; exit 1&quot;</span><br>  &#125;,<br>  <span class="hljs-string">&quot;keywords&quot;</span>: [<br>    <span class="hljs-string">&quot;标哥&quot;</span>,<br>    <span class="hljs-string">&quot;nodejs第一步&quot;</span><br>  ],<br>  <span class="hljs-string">&quot;author&quot;</span>: <span class="hljs-string">&quot;标哥哥&quot;</span>,<br>  <span class="hljs-string">&quot;license&quot;</span>: <span class="hljs-string">&quot;MIT&quot;</span>,<br>  <span class="hljs-string">&quot;dependencies&quot;</span>: &#123;<br>    <span class="hljs-string">&quot;bootstrap&quot;</span>: <span class="hljs-string">&quot;^5.1.3&quot;</span><br>  &#125;,<br>  <span class="hljs-string">&quot;devDependencies&quot;</span>: &#123;<br>    <span class="hljs-string">&quot;jquery&quot;</span>: <span class="hljs-string">&quot;^3.6.0&quot;</span><br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><code>dependencies</code>是属于生产依赖，它是由<code>--save</code>来自动添加的</li>
<li><code>devDependencies</code>是属于开发依赖，它是由<code>--save-dev</code>来自动添加的</li>
</ul>
<p>一个包具体是开发依赖还是生产依赖后期我们在讲<code>webpack</code>的时候再来区分</p>
<p>当我们把安装包的信息记录在了<code>package.json</code>里面以后，后期如果项目再进行传递发布，或者发送给别人的时应该不需要把<code>node_modules</code>文件夹给别人，因为这里面的包是针对于当前的系统及平台的，可能不适用于目标平台，所以我们一般在传递node.js项目的时候都会把这个<code>node_module</code>给删除，只给源代码别人</p>
<h3 id="根据package-json记录信息重构包"><a href="#根据package-json记录信息重构包" class="headerlink" title="根据package.json记录信息重构包"></a>根据package.json记录信息重构包</h3><p>当别人拿到这个nodejs的项目以后是不能直接运行的，因为里面使用了第三方包，只要是<code>package.json</code>记录了每一次的安装信息，那么，后期在构建这个项目的时候就只需要执行以下命令即可</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install<br></code></pre></td></tr></table></figure>

<h3 id="安装指定版本"><a href="#安装指定版本" class="headerlink" title="安装指定版本"></a>安装指定版本</h3><p>之前我们在安装远程包的时候，我们都是默认安装的最新版本，例如我们在装<code>bootstrap</code>这个包的时候装的就是5的版本，现在我们希望安装3的版本，怎么办呢</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm info bootstrap@3<br></code></pre></td></tr></table></figure>

<p>上面的命令就会把所以<code>bootstrap</code>以3开头的版本信息展示出来</p>
<p>当我们查询到了指定的版本信息以后，我们就可以再次使用下在的命令来安装</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install bootstrap@3.3.7 --save<br></code></pre></td></tr></table></figure>

<h3 id="npm-uninstall卸载包"><a href="#npm-uninstall卸载包" class="headerlink" title="npm uninstall卸载包"></a>npm uninstall卸载包</h3><p>当我们安装一个包以后，如果发现这个包不需要或安装错了，我们就要卸载这个包</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm uninstall 包名<br></code></pre></td></tr></table></figure>

<p>如下，我们卸载刚刚下载的bootstrap的包</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm uninstall bootstrap<br></code></pre></td></tr></table></figure>

<p>卸载完了以后，package.json里面记录信息也会同步删除</p>
<h3 id="npm国内镜像设置"><a href="#npm国内镜像设置" class="headerlink" title="npm国内镜像设置"></a>npm国内镜像设置</h3><p>npm远程仓库的服务器是在国外的，所以我们如果下载包的时候会有下面的现象产生</p>
<p><img src="https://pic.imgdb.cn/item/61681d9f2ab3f51d91719db0.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211014115208443"></p>
<p>每次下载包都要从国外的服务器去下载 ，但是因为XX原因，我们访问国外的服务器都比较慢，所以一般开发当中，我们都要把远程地址使用代理指向国内，目前的解决方案有以下几种</p>
<ol>
<li>更改npm 镜像地址</li>
<li>使用国内包管理工具cnpm</li>
<li>使用yarn包管理工具</li>
</ol>
<p>目前最简单的我们是使用<code>npm</code>来完成</p>
<p><img src="https://pic.imgdb.cn/item/61681dcb2ab3f51d9171e90d.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211014115826587"></p>
<hr>
<h2 id="4-使用axios-cheerio完成数据抓取"><a href="#4-使用axios-cheerio完成数据抓取" class="headerlink" title="4.使用axios+cheerio完成数据抓取"></a>4.使用axios+cheerio完成数据抓取</h2><p>完成当前功能主要使用两个包</p>
<ol>
<li><code>axios</code>这个包是一个跨平台的包，可以在node.js平台下面使用，也可以在浏览器环境下面使用，是一个主流的包</li>
<li><code>cheerio</code>包，这个包可以分析html代码，然后从html代码当中提取提自己所需要的信息</li>
</ol>
<h3 id="模块浏览器请求数据"><a href="#模块浏览器请求数据" class="headerlink" title="模块浏览器请求数据"></a>模块浏览器请求数据</h3><p><img src="https://pic.imgdb.cn/item/61681df32ab3f51d9172290a.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211014141742716"></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//如果在导包的时候，没有输入路径 ，默认先从当前项目文件夹的node_modules里面找，如果找到了直接 使用</span><br><span class="hljs-comment">//如果找不到就从系统安装目录里去找</span><br><br><span class="hljs-comment">//第一步：导包</span><br><span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;axios&quot;</span>).default;<br><br><span class="hljs-comment">//第二步：准备要请求的URL地址</span><br><span class="hljs-keyword">let</span> u1 = <span class="hljs-string">`https://v.qq.com/channel/tv?listpage=1&amp;channel=tv&amp;feature=9`</span>;<br><br><span class="hljs-keyword">const</span> getData = <span class="hljs-keyword">async</span> () =&gt; &#123;<br>    <span class="hljs-comment">//第三步：模拟请求，打开这个网站</span><br>    <span class="hljs-keyword">let</span> resp = <span class="hljs-keyword">await</span> axios.get(u1, &#123;<br>        <span class="hljs-attr">headers</span>: &#123;<br>            <span class="hljs-attr">accept</span>: <span class="hljs-string">&quot;text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9&quot;</span>,<br>            <span class="hljs-string">&quot;accept-encoding&quot;</span>: <span class="hljs-string">&quot;gzip, deflate, br&quot;</span>,<br>            <span class="hljs-string">&quot;accept-language&quot;</span>: <span class="hljs-string">&quot;zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6&quot;</span>,<br>            <span class="hljs-attr">cookie</span>: <span class="hljs-string">&quot;pgv_pvid=1615445184; fqm_pvqid=b1b327f8-8c15-4ee3-a946-1ecb364bc3e5; tvfe_boss_uuid=4bd7a2c0df6b1e8c; ptui_loginuin=365055754@qq.com; pt_sms_phone=186******06; RK=bC7NQrH6TO; ptcz=1b4cb6c8f9018069c14ba596f51de01f7190793d1cafdcdafa6e8f32009cc5d8; ts_refer=www.baidu.com/link; ts_uid=4146027010; video_guid=cd38096b25ee0579; video_platform=2; pgv_info=ssid=s4164181250; bucket_id=9231009; ts_last=v.qq.com/channel/tv; qv_als=LNXo3zN/8SkqEg/AA11634191083lufU8w==; ptag=|channel; ad_play_index=59&quot;</span>,<br>            <span class="hljs-string">&quot;user-agent&quot;</span>: <span class="hljs-string">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36 Edg/94.0.992.47&quot;</span><br>        &#125;<br>    &#125;);<br>    <span class="hljs-comment">//第四步：服务器响应的数据在data里面</span><br>    <span class="hljs-built_in">console</span>.log(resp.data);<br>&#125;<br>getData();<br></code></pre></td></tr></table></figure>

<p>经过上面的代码以后，我们就可以得到服务器返回的数据，这个数据就是浏览器请求一个网站以后返回的结果 ，我们可以看到它是一个HTML字符串</p>
<ul>
<li><code>axios</code>是用于模拟http请求的</li>
<li><code>axios</code>是基于Promise的技术，所以我们可以使用<code>await</code>来实现异步</li>
<li>请求结果在<code>resp</code>，可以认为是<code>response</code>响应的单词的简称</li>
</ul>
<h3 id="分析得到的结果"><a href="#分析得到的结果" class="headerlink" title="分析得到的结果"></a>分析得到的结果</h3><p>当我们通过模拟请求得到数据以后，我们现在需要分析上面的结果 ，然后提取出自己所需要的数据</p>
<p><img src="https://pic.imgdb.cn/item/61681df32ab3f51d9172290a.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211014141832745"></p>
<p>我们可以到在审查元素里在我们所需要的DOM信息，如果我们得到的这些字符串能像DOM操作一样进行操作，这就很方便了</p>
<p>这个时候<code>cheerio</code>就可以实现这个功能，这个包主要的作用如下所示</p>
<p><img src="https://pic.imgdb.cn/item/61681eb02ab3f51d91736808.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211014142024990"></p>
<p>它主要的一点就可以把字符串当成dom文档 使用jQuery去操作，现在我们就去安装这个包</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install cheerio --save<br></code></pre></td></tr></table></figure>

<p>接上面的代码，我们写在继续 </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//如果在导包的时候，没有输入路径 ，默认先从当前项目文件夹的node_modules里面找，如果找到了直接 使用</span><br><span class="hljs-comment">//如果找不到就从系统安装目录里去找</span><br><br><span class="hljs-comment">//第一步：导包</span><br><span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;axios&quot;</span>).default;<br><span class="hljs-keyword">const</span> cheerio = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;cheerio&quot;</span>);<br><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;path&quot;</span>);<br><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;fs&quot;</span>);<br><br><span class="hljs-comment">//第二步：准备要请求的URL地址</span><br><span class="hljs-keyword">let</span> u1 = <span class="hljs-string">`https://v.qq.com/channel/tv?listpage=1&amp;channel=tv&amp;feature=9`</span>;<br><br><span class="hljs-keyword">const</span> getData = <span class="hljs-keyword">async</span> () =&gt; &#123;<br>    <span class="hljs-comment">//第三步：模拟请求，打开这个网站</span><br>    <span class="hljs-keyword">let</span> resp = <span class="hljs-keyword">await</span> axios.get(u1, &#123;<br>        <span class="hljs-attr">headers</span>: &#123;<br>            <span class="hljs-attr">accept</span>: <span class="hljs-string">&quot;text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9&quot;</span>,<br>            <span class="hljs-string">&quot;accept-encoding&quot;</span>: <span class="hljs-string">&quot;gzip, deflate, br&quot;</span>,<br>            <span class="hljs-string">&quot;accept-language&quot;</span>: <span class="hljs-string">&quot;zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6&quot;</span>,<br>            <span class="hljs-attr">cookie</span>: <span class="hljs-string">&quot;pgv_pvid=1615445184; fqm_pvqid=b1b327f8-8c15-4ee3-a946-1ecb364bc3e5; tvfe_boss_uuid=4bd7a2c0df6b1e8c; ptui_loginuin=365055754@qq.com; pt_sms_phone=186******06; RK=bC7NQrH6TO; ptcz=1b4cb6c8f9018069c14ba596f51de01f7190793d1cafdcdafa6e8f32009cc5d8; ts_refer=www.baidu.com/link; ts_uid=4146027010; video_guid=cd38096b25ee0579; video_platform=2; pgv_info=ssid=s4164181250; bucket_id=9231009; ts_last=v.qq.com/channel/tv; qv_als=LNXo3zN/8SkqEg/AA11634191083lufU8w==; ptag=|channel; ad_play_index=59&quot;</span>,<br>            <span class="hljs-string">&quot;user-agent&quot;</span>: <span class="hljs-string">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36 Edg/94.0.992.47&quot;</span><br>        &#125;<br>    &#125;);<br>    <span class="hljs-comment">//第四步：服务器响应的数据在data里面</span><br>    <span class="hljs-keyword">let</span> htmlStr = resp.data;       <span class="hljs-comment">//它是一个html的字符串</span><br>    <span class="hljs-comment">//第五步：我们要分析这个字符串，提取有用的数据,先使用cheerio将上面的html字符串转换成dom模型</span><br>    <span class="hljs-keyword">let</span> $ = cheerio.load(htmlStr);<br>    <span class="hljs-keyword">let</span> result = [];<br>    $(<span class="hljs-string">&quot;.mod_figure&gt;.list_item&quot;</span>).each(<span class="hljs-function">(<span class="hljs-params">index, item</span>) =&gt;</span> &#123;<br>        <span class="hljs-keyword">let</span> obj = &#123;&#125;<br>        obj.href = $(item).children(<span class="hljs-string">&quot;a&quot;</span>).attr(<span class="hljs-string">&quot;href&quot;</span>);<br>        obj.title = $(item).children(<span class="hljs-string">&quot;a&quot;</span>).attr(<span class="hljs-string">&quot;title&quot;</span>);<br>        obj.desc = $(item).find(<span class="hljs-string">&quot;.figure_desc&quot;</span>).text();    <span class="hljs-comment">//描述信息</span><br>        obj.tag = $(item).find(<span class="hljs-string">&quot;.figure_caption&quot;</span>).text();  <span class="hljs-comment">//更新到多少集</span><br>        obj.imgSrc = $(item).find(<span class="hljs-string">&quot;.figure_pic&quot;</span>).attr(<span class="hljs-string">&quot;src&quot;</span>);  <span class="hljs-comment">//图片地址</span><br>        result.push(obj);<br>    &#125;);<br><br>    <span class="hljs-comment">//第六步：遍历结束，将数组转换成json字符串</span><br>    <span class="hljs-keyword">let</span> jsonStr = <span class="hljs-built_in">JSON</span>.stringify(result);<br>    <span class="hljs-comment">//第七步：写入到自己的文件</span><br>    <span class="hljs-keyword">let</span> saveData = path.join(__dirname, <span class="hljs-string">&quot;./QQVideo.json&quot;</span>);<br>    fs.writeFileSync(saveData, jsonStr);<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;写入成功&quot;</span>);<br>    <span class="hljs-comment">//第八步：插入到自己的数据库</span><br><br>&#125;<br><br>getData();<br></code></pre></td></tr></table></figure>

<p>在上面的代码里面，我们在之前的代码上面分析了得到的请求结果字符串，然后使用<code>cheerio</code>来转换成了DOM的结构分析，最后将我们所需要的信息保存到了一个对象，将对象集中起来放在了数组里在，最后转成JSON字符串保存到了文件</p>
<h3 id="抓取图片"><a href="#抓取图片" class="headerlink" title="抓取图片"></a>抓取图片</h3><p>当我们得到了上面的信息以后，我们其实就已经完成了50%的功能了，现在我们在文件里面可以看到有一个属性叫<code>imgSrc</code>，这个属性用于保存了图片地址，所以我们可以再次根据这个地址去抓取图片，把它下载到本地</p>
<p><img src="https://pic.imgdb.cn/item/61681f0a2ab3f51d9173f37e.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211014160120191"></p>
<p>上图就是下载文件的过程，我们使用了FS的另一个功能文件流<code>File Stream</code>的功能</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//如果在导包的时候，没有输入路径 ，默认先从当前项目文件夹的node_modules里面找，如果找到了直接 使用</span><br><span class="hljs-comment">//如果找不到就从系统安装目录里去找</span><br><br><span class="hljs-comment">//第一步：导包</span><br><span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;axios&quot;</span>).default;<br><span class="hljs-keyword">const</span> cheerio = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;cheerio&quot;</span>);<br><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;path&quot;</span>);<br><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;fs&quot;</span>);<br><br><span class="hljs-comment">//第二步：准备要请求的URL地址</span><br><span class="hljs-keyword">let</span> u1 = <span class="hljs-string">`https://v.qq.com/channel/tv?listpage=1&amp;channel=tv&amp;feature=9`</span>;<br><br><span class="hljs-comment">//准备axios请求的配置信息</span><br><span class="hljs-keyword">let</span> config = &#123;<br>    <span class="hljs-attr">headers</span>: &#123;<br>        <span class="hljs-attr">accept</span>: <span class="hljs-string">&quot;text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9&quot;</span>,<br>        <span class="hljs-string">&quot;accept-encoding&quot;</span>: <span class="hljs-string">&quot;gzip, deflate, br&quot;</span>,<br>        <span class="hljs-string">&quot;accept-language&quot;</span>: <span class="hljs-string">&quot;zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6&quot;</span>,<br>        <span class="hljs-attr">cookie</span>: <span class="hljs-string">&quot;pgv_pvid=1615445184; fqm_pvqid=b1b327f8-8c15-4ee3-a946-1ecb364bc3e5; tvfe_boss_uuid=4bd7a2c0df6b1e8c; ptui_loginuin=365055754@qq.com; pt_sms_phone=186******06; RK=bC7NQrH6TO; ptcz=1b4cb6c8f9018069c14ba596f51de01f7190793d1cafdcdafa6e8f32009cc5d8; ts_refer=www.baidu.com/link; ts_uid=4146027010; video_guid=cd38096b25ee0579; video_platform=2; pgv_info=ssid=s4164181250; bucket_id=9231009; ts_last=v.qq.com/channel/tv; qv_als=LNXo3zN/8SkqEg/AA11634191083lufU8w==; ptag=|channel; ad_play_index=59&quot;</span>,<br>        <span class="hljs-string">&quot;user-agent&quot;</span>: <span class="hljs-string">&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36 Edg/94.0.992.47&quot;</span><br>    &#125;<br>&#125;<br><br><span class="hljs-keyword">const</span> getData = <span class="hljs-keyword">async</span> () =&gt; &#123;<br>    <span class="hljs-comment">//第三步：模拟请求，打开这个网站</span><br>    <span class="hljs-keyword">let</span> resp = <span class="hljs-keyword">await</span> axios.get(u1, config);<br>    <span class="hljs-comment">//第四步：服务器响应的数据在data里面</span><br>    <span class="hljs-keyword">let</span> htmlStr = resp.data;       <span class="hljs-comment">//它是一个html的字符串</span><br>    <span class="hljs-comment">//第五步：我们要分析这个字符串，提取有用的数据,先使用cheerio将上面的html字符串转换成dom模型</span><br>    <span class="hljs-keyword">let</span> $ = cheerio.load(htmlStr);<br>    <span class="hljs-keyword">let</span> result = [];<br>    $(<span class="hljs-string">&quot;.mod_figure&gt;.list_item&quot;</span>).each(<span class="hljs-function">(<span class="hljs-params">index, item</span>) =&gt;</span> &#123;<br>        <span class="hljs-keyword">let</span> obj = &#123;&#125;<br>        obj.href = $(item).children(<span class="hljs-string">&quot;a&quot;</span>).attr(<span class="hljs-string">&quot;href&quot;</span>);<br>        obj.title = $(item).children(<span class="hljs-string">&quot;a&quot;</span>).attr(<span class="hljs-string">&quot;title&quot;</span>);<br>        obj.desc = $(item).find(<span class="hljs-string">&quot;.figure_desc&quot;</span>).text();    <span class="hljs-comment">//描述信息</span><br>        obj.tag = $(item).find(<span class="hljs-string">&quot;.figure_caption&quot;</span>).text();  <span class="hljs-comment">//更新到多少集</span><br>        obj.imgSrc = $(item).find(<span class="hljs-string">&quot;.figure_pic&quot;</span>).attr(<span class="hljs-string">&quot;src&quot;</span>);  <span class="hljs-comment">//图片地址</span><br>        result.push(obj);<br>    &#125;);<br><br>    <span class="hljs-comment">//第六步：遍历结束，将数组转换成json字符串</span><br>    <span class="hljs-keyword">let</span> jsonStr = <span class="hljs-built_in">JSON</span>.stringify(result);<br>    <span class="hljs-comment">//第七步：写入到自己的文件</span><br>    <span class="hljs-keyword">let</span> saveData = path.join(__dirname, <span class="hljs-string">&quot;./QQVideo.json&quot;</span>);<br>    fs.writeFileSync(saveData, jsonStr);<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;写入成功&quot;</span>);<br>    <span class="hljs-comment">//第八步：插入到自己的数据库</span><br><br>    <span class="hljs-comment">//第九步：下载图片</span><br>    <span class="hljs-comment">//第十步：准备存放图片的文件夹，例如 ，我想放在当前目录的movieImgs</span><br>    <span class="hljs-keyword">let</span> movieImgsPath = path.join(__dirname, <span class="hljs-string">&quot;./movieImgs&quot;</span>);<br>    <span class="hljs-keyword">if</span> (!fs.existsSync(movieImgsPath)) &#123;<br>        <span class="hljs-comment">//不存在就创建</span><br>        fs.mkdirSync(movieImgsPath);<br>    &#125;<br>    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> item <span class="hljs-keyword">of</span> result) &#123;<br>        <span class="hljs-comment">//遍历以后拼接图片的地址</span><br>        <span class="hljs-keyword">let</span> u2 = <span class="hljs-string">`https:<span class="hljs-subst">$&#123;item.imgSrc&#125;</span>`</span>;<br>        <span class="hljs-comment">//这里要注意，之前请求网页的时候返回的是文字 ，但是这个时候请求的时候返回的是图片</span><br>        <span class="hljs-comment">//图片不能够直接使用文字 去表示</span><br>        <span class="hljs-keyword">let</span> resp = <span class="hljs-keyword">await</span> axios.get(u2, &#123;<br>            ...config,<br>            <span class="hljs-attr">responseType</span>: <span class="hljs-string">&quot;stream&quot;</span><br>        &#125;);<br>        <span class="hljs-comment">// console.log(resp.data);   //它是一个流</span><br>        <span class="hljs-comment">//创建当前这个图片路径</span><br>        <span class="hljs-keyword">let</span> currentImgPath = path.join(movieImgsPath, <span class="hljs-string">`<span class="hljs-subst">$&#123;item.title&#125;</span>.png`</span>);<br>        <span class="hljs-comment">//将图片变成一个写入流，可以通过这个流向文件里面写入数据</span><br>        <span class="hljs-keyword">let</span> currentImgStream = fs.createWriteStream(currentImgPath);<br>        <span class="hljs-comment">// 两个流对接</span><br>        resp.data.pipe(currentImgStream);<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;图片下载成功&quot;</span>);<br>    &#125;<br><br>&#125;<br><br>getData();<br></code></pre></td></tr></table></figure>

<p>在上面的代码里面，我们主要是有两个技术</p>
<ol>
<li>在<code>axios</code>的请求过程当中，我们把响应的数据类型变成了<code>stream</code></li>
<li>我们使用文件流<code>fs.createWriteStream()</code>来写入文件数据，这样会非常方便</li>
</ol>
<h2 id="5-使用nodemailer发送邮件"><a href="#5-使用nodemailer发送邮件" class="headerlink" title="5.使用nodemailer发送邮件"></a>5.使用nodemailer发送邮件</h2><p>在以后的项目当中，我们经常需要使用到邮件验证码，或者向用户的邮箱里面发送邮件，如批量发送，自动发送等。这佣时候我们就需要使用到nodejs编写的程序来自动发送</p>
<p>在npmjs里面有很多发送邮件的包，目前使用得比较多的就是<code>nodemailer</code></p>
<p><strong>第一步</strong>：安装所需要的包</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install nodemailer <br></code></pre></td></tr></table></figure>

<p><strong>第二步：</strong>准备发送的账号和接收邮件的地址</p>
<p>目前我们准备使用163的邮箱去发送，这个时候进行相关的配置，现阶段我们以163的邮箱去配置</p>
<img src="https://pic.imgdb.cn/item/616977c62ab3f51d914cc0b3.png" srcset="/blog/img/loading.gif" lazyload style="zoom: 50%;" />

<p><img src="https://pic.imgdb.cn/item/616978d22ab3f51d914dcf74.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211015093009547"></p>
<p>上面的imap，smtp，以及pop3都要开启，当我们开启了以后，我们就可以配置服务器</p>
<p><img src="https://pic.imgdb.cn/item/616978d22ab3f51d914dcf74.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211015093130219"></p>
<p>同学们在这里要记住自己授权密码，不要告诉别人</p>
<p>具体的网易163的设置信息可以参考下面的网址</p>
<p><a target="_blank" rel="noopener" href="https://help.mail.163.com/faqDetail.do?code=d7a5dc8471cd0c0e8b4b8f4f8e49998b374173cfe9171305fa1ce630d7f67ac2cda80145a1742516">https://help.mail.163.com/faqDetail.do?code=d7a5dc8471cd0c0e8b4b8f4f8e49998b374173cfe9171305fa1ce630d7f67ac2cda80145a1742516</a></p>
<p><img src="https://pic.imgdb.cn/item/616979232ab3f51d914e283c.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211015093149269"></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> nodemailer = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;nodemailer&quot;</span>);<br><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;path&quot;</span>);<br><br><br><span class="hljs-keyword">let</span> sendMail = <span class="hljs-keyword">async</span> () =&gt; &#123;<br>    <span class="hljs-comment">//在发送邮件之前，一定要先创建一个发送者</span><br>    <span class="hljs-keyword">let</span> passport = nodemailer.createTransport(&#123;<br>        <span class="hljs-attr">host</span>: <span class="hljs-string">&quot;smtp.163.com&quot;</span>,<br>        <span class="hljs-attr">port</span>: <span class="hljs-number">465</span>,<br>        <span class="hljs-attr">auth</span>: &#123;<br>            <span class="hljs-attr">user</span>: <span class="hljs-string">&quot;mh475201314@163.com&quot;</span>,<br>            <span class="hljs-comment">//这里填写自己的授权码</span><br>            <span class="hljs-attr">pass</span>: <span class="hljs-string">&quot;***************&quot;</span><br>        &#125;<br>    &#125;);<br><br><br>    <span class="hljs-keyword">try</span> &#123;<br>        <span class="hljs-keyword">let</span> result = <span class="hljs-keyword">await</span> passport.sendMail(&#123;<br>            <span class="hljs-attr">subject</span>: <span class="hljs-string">&quot;标哥哥的第一封邮件&quot;</span>,<br>            <span class="hljs-attr">from</span>: <span class="hljs-string">&quot;mh475201314@163.com&quot;</span>,<br>            <span class="hljs-attr">to</span>: [<br>                <span class="hljs-string">&quot;1011782688@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;1765868749@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;1765868749@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;2651285539@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;2644202703@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;2251143937@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;593507091@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;alice-ti@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;209153464@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;2237755280@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;892237544@.com&quot;</span>,<br>                <span class="hljs-string">&quot;1752337444@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;1007042505@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;1098921179@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;2953586388@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;2723837943@qq.com&quot;</span>,<br>                <span class="hljs-string">&quot;qq1291773807@163.com&quot;</span><br>            ],<br>            <span class="hljs-attr">cc</span>: <span class="hljs-string">&quot;lovesnsfi@163.com&quot;</span>,<br>            <span class="hljs-attr">text</span>: <span class="hljs-string">`</span><br><span class="hljs-string">            亲爱的各位小伙伴：</span><br><span class="hljs-string">            你好们！</span><br><span class="hljs-string">            我怀着无比沉痛的心情告诉他我们一个坏消息，明天要上课！请准备好你们的电脑 ，收拾好你们的心情，</span><br><span class="hljs-string">            带上笑容，带着希望来到这个令你无比向往的教室</span><br><span class="hljs-string">    </span><br><span class="hljs-string">                                                                你们可爱的桃子老师</span><br><span class="hljs-string">                                                                <span class="hljs-subst">$&#123;<span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toLocaleString()&#125;</span></span><br><span class="hljs-string">        `</span>,<br>            <span class="hljs-attr">attachments</span>: [<br>                &#123;<br>                    <span class="hljs-attr">filename</span>: <span class="hljs-string">&quot;标哥哥的帅照片.jpg&quot;</span>,<br>                    <span class="hljs-attr">path</span>: path.join(__dirname, <span class="hljs-string">&quot;./yangbiao2021.jpg&quot;</span>),<br>                    <br>                &#125;, &#123;<br>                    <span class="hljs-attr">filename</span>: <span class="hljs-string">&quot;标哥班的通讯录.txt&quot;</span>,<br>                    <span class="hljs-attr">path</span>: path.join(__dirname, <span class="hljs-string">&quot;./list.txt&quot;</span>)<br>                &#125;<br>            ]<br>        &#125;);<br><br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;邮件发送成功&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(result);<br>    &#125; <span class="hljs-keyword">catch</span> (error) &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;邮件发送失败&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(error);<br>    &#125;<br>&#125;<br><br>sendMail();<br></code></pre></td></tr></table></figure>

<h2 id="6-使用node-xlsx操作excel"><a href="#6-使用node-xlsx操作excel" class="headerlink" title="6.使用node-xlsx操作excel"></a>6.使用node-xlsx操作excel</h2><p>在nodejs里面，我们经常需要使用excel的导入与导出功能，如下图所示</p>
<p><img src="https://pic.imgdb.cn/item/6169793c2ab3f51d914e4004.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211015104240020">在nodejs里面，我们有第三方的包来操作这个excel，这个包就是<code>node-xlsx</code></p>
<p><strong>第一步</strong>：安装包</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install node-xlsx<br></code></pre></td></tr></table></figure>

<h3 id="读取excel"><a href="#读取excel" class="headerlink" title="读取excel"></a>读取excel</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;path&quot;</span>);<br><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;fs&quot;</span>);<br><span class="hljs-keyword">const</span> xlsx = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;node-xlsx&quot;</span>).default;<br><span class="hljs-comment">//读取excel</span><br><span class="hljs-keyword">const</span> readExcel = <span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-comment">//第一步：先构建路径 ，准备读取的excel的文件路径 </span><br>    <span class="hljs-keyword">let</span> p1 = path.join(__dirname, <span class="hljs-string">&quot;./stuinfo.xlsx&quot;</span>);<br>    <span class="hljs-comment">//第二步：读取</span><br>    <span class="hljs-keyword">let</span> result = xlsx.parse(p1);<br>    <span class="hljs-built_in">console</span>.log(result);<br>&#125;<br>readExcel();<br></code></pre></td></tr></table></figure>

<p>代码运行的结果如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs javascript">[<br>  &#123;<br>    <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;stuinfo&#x27;</span>,<br>    <span class="hljs-attr">data</span>: [<br>      [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>],<br>      [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>],<br>      [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>],<br>      [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>],<br>      [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>],<br>      [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>],<br>      [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>], [<span class="hljs-built_in">Array</span>]<br>    ]<br>  &#125;,<br>  &#123; <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;Sheet1&#x27;</span>, <span class="hljs-attr">data</span>: [] &#125;<br>]<br></code></pre></td></tr></table></figure>

<img src="https://pic.imgdb.cn/item/6169794c2ab3f51d914e5009.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211015105701916"  />

<p>通过上面代码运行的结果与图片对比，我们发现，excel的工作薄里有两个工作表，所以得到的结果里面也是一个数组，这个数组里有2个对象，name属性就是工用表的名称，data是一个二维数组，代表的是当前excel工作表里面的数据</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript">[<br>  [<br>    <span class="hljs-string">&#x27;sid&#x27;</span>,     <span class="hljs-string">&#x27;sname&#x27;</span>,<span class="hljs-string">&#x27;ssex&#x27;</span>,    <span class="hljs-string">&#x27;sbirthday&#x27;</span>,<span class="hljs-string">&#x27;snation&#x27;</span>, <span class="hljs-string">&#x27;saddr&#x27;</span>,<span class="hljs-string">&#x27;smail&#x27;</span>,   <span class="hljs-string">&#x27;stel&#x27;</span><br>  ],<br>  [<br>    <span class="hljs-number">2005010101</span>,<br>    <span class="hljs-string">&#x27;苏俊丹       &#x27;</span>,<br>    <span class="hljs-string">&#x27;女&#x27;</span>,<br>    <span class="hljs-number">32752</span>,<br>    <span class="hljs-string">&#x27;汉族&#x27;</span>,<br>    <span class="hljs-string">&#x27;湖北省/武汉市/武昌区/光谷广场1号&#x27;</span>,<br>    <span class="hljs-string">&#x27;2005010101@softeem.com&#x27;</span>,<br>    <span class="hljs-number">13878841001</span><br>  ]<br>  <span class="hljs-comment">//省略.....</span><br>]<br></code></pre></td></tr></table></figure>

<p><img src="https://pic.imgdb.cn/item/6169795c2ab3f51d914e5e5b.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211015110059279"></p>
<p>上面的两个数组就要上面的excel里面的两行</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;path&quot;</span>);<br><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;fs&quot;</span>);<br><span class="hljs-keyword">const</span> xlsx = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;node-xlsx&quot;</span>).default;<br><br><br><span class="hljs-comment">//读取excel</span><br><br><span class="hljs-keyword">const</span> readExcel = <span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-comment">//第一步：先构建路径 ，准备读取的excel的文件路径 </span><br>    <span class="hljs-keyword">let</span> p1 = path.join(__dirname, <span class="hljs-string">&quot;./stuinfo.xlsx&quot;</span>);<br>    <span class="hljs-comment">//第二步：读取</span><br>    <span class="hljs-keyword">let</span> result = xlsx.parse(p1);<br>    <span class="hljs-comment">//第三步：得到excel的第一行数据，也就是表头</span><br>    <span class="hljs-keyword">let</span> headerRow = result[<span class="hljs-number">0</span>].data.shift();<br>    <span class="hljs-comment">//第四步：组建成对象\</span><br>    <span class="hljs-keyword">let</span> arr = []<br>    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> item <span class="hljs-keyword">of</span> result[<span class="hljs-number">0</span>].data) &#123;<br>        <span class="hljs-keyword">let</span> obj = &#123;&#125;<br>        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; headerRow.length; i++) &#123;<br>            obj[headerRow[i]] = item[i];<br>        &#125;<br>        arr.push(obj)<br>    &#125;<br>    <span class="hljs-comment">//第五步：写入一个JSON文件</span><br>    <span class="hljs-keyword">let</span> jsonSavePath = path.join(__dirname, <span class="hljs-string">&quot;./stuinfo.json&quot;</span>);<br>    fs.writeFileSync(jsonSavePath, <span class="hljs-built_in">JSON</span>.stringify(arr));<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;写入完成&quot;</span>);<br>&#125;<br>readExcel();<br></code></pre></td></tr></table></figure>

<p>上面的代码我们就是将<code>excel</code>读取出来了以后，然后转成了 <code>json</code>字符串保存在了一个文件里面</p>
<h3 id="生成excel"><a href="#生成excel" class="headerlink" title="生成excel"></a>生成excel</h3><p>excel的生成操作还是使用比较频繁 的，因为我们后期经常会涉及到数据的导出功能</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 生成一个excel文件</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;path&quot;</span>);<br><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;fs&quot;</span>);<br><span class="hljs-keyword">const</span> xlsx = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;node-xlsx&quot;</span>).default;<br><br><br><span class="hljs-keyword">const</span> writeExcel = <span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-comment">//第一步：先构建要读取的文件的路径 </span><br>    <span class="hljs-keyword">let</span> p1 = path.join(__dirname, <span class="hljs-string">&quot;./result.json&quot;</span>);<br>    <span class="hljs-comment">//第二步：读取这个文件,得到buff</span><br>    <span class="hljs-keyword">let</span> buff = fs.readFileSync(p1);<br>    <span class="hljs-keyword">let</span> jsonStr = buff.toString();<br>    <span class="hljs-comment">// 将之前的buffer转成json字符串以后，再转变成对象</span><br>    <span class="hljs-comment">/** <span class="hljs-doctag">@type <span class="hljs-type">&#123;Array&#125;</span> </span>*/</span><br>    <span class="hljs-keyword">let</span> arr = <span class="hljs-built_in">JSON</span>.parse(jsonStr);<br>    <span class="hljs-keyword">if</span> (arr.length &gt; <span class="hljs-number">0</span>) &#123;<br>        <span class="hljs-comment">// 第三步：构造了工作表的对象</span><br>        <span class="hljs-keyword">let</span> excelObj = &#123;<br>            <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;Sheet1&quot;</span>,<br>            <span class="hljs-attr">data</span>: []<br>        &#125;;<br>        <span class="hljs-comment">//第四步：得到表头</span><br>        <span class="hljs-keyword">let</span> headerRow = <span class="hljs-built_in">Object</span>.keys(arr[<span class="hljs-number">0</span>]);   <span class="hljs-comment">//[&quot;newsTitle&quot;,&quot;newsTime&quot;,&quot;newsLink&quot;,&quot;newsContent&quot;,&quot;readCount&quot;]</span><br>        excelObj.data.push(headerRow);<br>        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> item <span class="hljs-keyword">of</span> arr) &#123;<br>            excelObj.data.push(<span class="hljs-built_in">Object</span>.values(item))<br>        &#125;<br>        <span class="hljs-comment">//第五步：生成excel</span><br>        <span class="hljs-keyword">let</span> excelBuff = xlsx.build([excelObj]);<br>        <span class="hljs-comment">//第六步：构建保存文件的路径</span><br>        <span class="hljs-keyword">let</span> excelSavePath = path.join(__dirname, <span class="hljs-string">&quot;./result.xlsx&quot;</span>);<br>        <span class="hljs-comment">//第七步：写入</span><br>        fs.writeFileSync(excelSavePath,excelBuff);<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;生成成功&quot;</span>);<br>    &#125;<br>&#125;<br>writeExcel();<br></code></pre></td></tr></table></figure>

<p><strong>总结</strong>：</p>
<ol>
<li><code>parse()</code>是用于读取excel文件的，它会返回一个数组，这个数组里包含的就是工作表对象</li>
<li><code>build()</code>是用于生成了<code>buffer</code>数据的，然后可以通过nodejs里面的<code>fs.writeFileSync</code>写入到一个文件里面</li>
<li>一个工作薄(workbook)里面包含多个工作表(worksheet)</li>
</ol>
<h2 id="7-nodejs连接mysql数据库"><a href="#7-nodejs连接mysql数据库" class="headerlink" title="7.nodejs连接mysql数据库"></a>7.nodejs连接mysql数据库</h2><p>现在我们使用是nodejs的后台，所以我们现在要学习如何使用nodejs连接mysql数据库以后进行相关的操作，以前的前端可能使用提php+mysql</p>
<p>在nodejs平台下面有第三方的包来操作数据库，这个包就叫mysql或mysql2</p>
<h3 id="安装第三方模块mysql"><a href="#安装第三方模块mysql" class="headerlink" title="安装第三方模块mysql"></a>安装第三方模块mysql</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install mysql --save<br></code></pre></td></tr></table></figure>

<p>上面的包就是操作mysql的nodejs第三方包，我们直接安装即可</p>
<h3 id="创建数据库连接"><a href="#创建数据库连接" class="headerlink" title="创建数据库连接"></a>创建数据库连接</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> mysql = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;mysql&quot;</span>);<br><br><span class="hljs-comment">//第一步：创建数据库的连接对象</span><br><span class="hljs-keyword">const</span> conn = mysql.createConnection(&#123;<br>    <span class="hljs-attr">host</span>: <span class="hljs-string">&quot;127.0.0.1&quot;</span>,<br>    <span class="hljs-attr">port</span>: <span class="hljs-number">3306</span>,<br>    <span class="hljs-attr">user</span>: <span class="hljs-string">&quot;dev_h2103&quot;</span>,<br>    <span class="hljs-attr">password</span>: <span class="hljs-string">&quot;123456&quot;</span>,<br>    <span class="hljs-attr">database</span>: <span class="hljs-string">&quot;test1018&quot;</span><br>&#125;);<br><br>conn.connect(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> &#123;<br>    <span class="hljs-keyword">if</span> (error) &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库连接失败&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(error);<br>    &#125;<br>    <span class="hljs-keyword">else</span> &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库连接成功&quot;</span>);<br>    &#125;<br>&#125;);<br></code></pre></td></tr></table></figure>

<h3 id="新增操作"><a href="#新增操作" class="headerlink" title="新增操作"></a>新增操作</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//新增操作</span><br><span class="hljs-comment">//1.1准备插入数据的SQL语句</span><br><span class="hljs-keyword">let</span> insertSql = <span class="hljs-string">`insert into h2103 (sname,ssex,sage) values (&quot;杨标&quot;,&quot;男&quot;,&quot;看书&quot;)`</span>;<br><span class="hljs-comment">//1.2执行SQL语句</span><br>conn.query(insertSql, <span class="hljs-function">(<span class="hljs-params">error,result</span>) =&gt;</span> &#123;<br>    <span class="hljs-comment">//这一条回调函数就是SQL语句所执行的结果</span><br>    <span class="hljs-comment">//1.3判断是否执行成功</span><br>    <span class="hljs-keyword">if</span>(error)&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行失败&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(error);<br>    &#125;<br>    <span class="hljs-keyword">else</span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行成功&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(result);<br>    &#125;<br>    <span class="hljs-comment">//1.4 数据库SQL语句执行完毕以后，一定关闭当前链接</span><br>    conn.end();<br>&#125;);<br></code></pre></td></tr></table></figure>

<h4 id="分析新增结果"><a href="#分析新增结果" class="headerlink" title="分析新增结果"></a>分析新增结果</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript">OkPacket &#123;<br>  <span class="hljs-attr">fieldCount</span>: <span class="hljs-number">0</span>,<br>  <span class="hljs-attr">affectedRows</span>: <span class="hljs-number">1</span>,<br>  <span class="hljs-attr">insertId</span>: <span class="hljs-number">1</span>,<br>  <span class="hljs-attr">serverStatus</span>: <span class="hljs-number">2</span>,<br>  <span class="hljs-attr">warningCount</span>: <span class="hljs-number">0</span>,<br>  <span class="hljs-attr">message</span>: <span class="hljs-string">&#x27;&#x27;</span>,<br>  <span class="hljs-attr">protocol41</span>: <span class="hljs-literal">true</span>,<br>  <span class="hljs-attr">changedRows</span>: <span class="hljs-number">0</span><br>&#125;<br></code></pre></td></tr></table></figure>

<p>上面的结果是数据库新增成功以后的结果，我们现在来分析一下这个结果</p>
<ul>
<li><code>affectedRows</code>受影响的行数，因为当前新增加了一条数据，所以有1行会受到影响</li>
<li><code>insertId</code>当前的数据表里面的id是自动增长的，这个就是返回的自动增长的id</li>
<li><code>changedRows</code>更改的行数，这个是后面修改的时候会体现</li>
</ul>
<h4 id="带参数的新增"><a href="#带参数的新增" class="headerlink" title="带参数的新增"></a>带参数的新增</h4><p>在执行SQL语句的时候，如果SQL语句当中有些东西需要是变量替换怎么办呢？这个时候我们就需要使用到SQL参数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//带参数的SQL语句新增</span><br><span class="hljs-comment">//1.1 准备SQL语句</span><br><span class="hljs-keyword">let</span> insertSql = <span class="hljs-string">`insert into h2103 (sname,ssex,hobby) values (?,?,?)`</span>;<br><span class="hljs-comment">//1.2 执行SQL语句</span><br>conn.query(insertSql, [<span class="hljs-string">&quot;杨标&quot;</span>, <span class="hljs-string">&quot;男&quot;</span>, <span class="hljs-string">&quot;写代码&quot;</span>], <span class="hljs-function">(<span class="hljs-params">error, results</span>) =&gt;</span> &#123;<br>    <span class="hljs-keyword">if</span>(error)&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行失败&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(error);<br>    &#125;<br>    <span class="hljs-keyword">else</span> &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行成功&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(results);<br>    &#125;<br>    conn.end();<br>&#125;);<br></code></pre></td></tr></table></figure>

<h3 id="修改操作"><a href="#修改操作" class="headerlink" title="修改操作"></a>修改操作</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//修改操作，将自己的爱好统一设置成“杨标打豆豆”</span><br><span class="hljs-comment">//1.1准备SQL语句</span><br><span class="hljs-keyword">let</span> updateSql = <span class="hljs-string">`update h2103 set hobby = ? where sname = ?`</span>;<br><span class="hljs-comment">//1.2执行SQL语句</span><br>conn.query(updateSql, [<span class="hljs-string">&quot;杨标打豆豆&quot;</span>, <span class="hljs-string">&quot;杨标&quot;</span>], <span class="hljs-function">(<span class="hljs-params">error, results</span>) =&gt;</span> &#123;<br>    <span class="hljs-keyword">if</span>(error)&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行失败&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(error);<br>    &#125;<br>    <span class="hljs-keyword">else</span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库的SQL语句执行成功&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(results);<br>    &#125;<br>    conn.end();<br>&#125;);<br></code></pre></td></tr></table></figure>

<h4 id="分析修改的结果"><a href="#分析修改的结果" class="headerlink" title="分析修改的结果"></a>分析修改的结果</h4><p>当数据库执行修改语句成功以后，我们打印results结果如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript">OkPacket &#123;<br>  <span class="hljs-attr">fieldCount</span>: <span class="hljs-number">0</span>,<br>  <span class="hljs-attr">affectedRows</span>: <span class="hljs-number">3</span>,<br>  <span class="hljs-attr">insertId</span>: <span class="hljs-number">0</span>,<br>  <span class="hljs-attr">serverStatus</span>: <span class="hljs-number">34</span>,<br>  <span class="hljs-attr">warningCount</span>: <span class="hljs-number">0</span>,<br>  <span class="hljs-attr">message</span>: <span class="hljs-string">&#x27;(Rows matched: 3  Changed: 3  Warnings: 0&#x27;</span>,<br>  <span class="hljs-attr">protocol41</span>: <span class="hljs-literal">true</span>,<br>  <span class="hljs-attr">changedRows</span>: <span class="hljs-number">3</span><br>&#125;<br></code></pre></td></tr></table></figure>

<ul>
<li><code>affectedRows</code>说明当前有3条数据受影响，那就是有3条数据被修改了</li>
<li><code>changedRows</code>说明有3条数据被修改了</li>
<li><code>message</code>：是服务在修改的时候返回的相关系统，如<code>Rows matched: 3</code>代表where条件匹配了3条数据，<code>Changed:3</code>代表修改了3条数据，<code>Warnings：0</code>代表没有警告</li>
</ul>
<p>后面要判断这个SQL语句是修改成功了就看<code>affectedRows</code>的属性值是否大于0即可</p>
<h3 id="删除操作"><a href="#删除操作" class="headerlink" title="删除操作"></a>删除操作</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//删除操作</span><br><span class="hljs-keyword">let</span> deleteSql = <span class="hljs-string">`delete from h2103 where sname = ?`</span>;<br>conn.query(deleteSql, [<span class="hljs-string">&quot;杨标&quot;</span>], <span class="hljs-function">(<span class="hljs-params">error, results</span>) =&gt;</span> &#123;<br>    <span class="hljs-keyword">if</span> (error) &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL执行失败&quot;</span>);<br>        log(error);<br>    &#125;<br>    <span class="hljs-keyword">else</span> &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行成功&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(results);<br>    &#125;<br>    conn.end();<br>&#125;);<br></code></pre></td></tr></table></figure>

<h4 id="分析删除的结果"><a href="#分析删除的结果" class="headerlink" title="分析删除的结果"></a>分析删除的结果</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs javascript">OkPacket &#123;<br>  <span class="hljs-attr">fieldCount</span>: <span class="hljs-number">0</span>,   <br>  <span class="hljs-attr">affectedRows</span>: <span class="hljs-number">3</span>, <br>  <span class="hljs-attr">insertId</span>: <span class="hljs-number">0</span>,     <br>  <span class="hljs-attr">serverStatus</span>: <span class="hljs-number">34</span>,<br>  <span class="hljs-attr">warningCount</span>: <span class="hljs-number">0</span>, <br>  <span class="hljs-attr">message</span>: <span class="hljs-string">&#x27;&#x27;</span>,     <br>  <span class="hljs-attr">protocol41</span>: <span class="hljs-literal">true</span>,<br>  <span class="hljs-attr">changedRows</span>: <span class="hljs-number">0</span>   <br>&#125;<br></code></pre></td></tr></table></figure>

<p>删除操作的结果与之前的结果是一样的对象，都是<code>OkPacket</code>，我们也是需要去看<code>affectedRows</code>这一个属性，如果这个属性大于0，则代表删除的行数大于总</p>
<h4 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h4><p>在数据库操作的过程当中，新增insert,修改update,删除delete它们返回的结果都是<code>OkPacket</code>，都要看<code>affectedRows</code>这个属性</p>
<hr>
<h3 id="查询操作"><a href="#查询操作" class="headerlink" title="查询操作"></a>查询操作</h3><p>数据库的查询操作与之前的新增，修改，删除不属于同一类型操作，它是一种特殊的操作，它查询以后是要返回结果给用户的</p>
<h4 id="普通查询"><a href="#普通查询" class="headerlink" title="普通查询"></a>普通查询</h4><p>这个地方是没有带参数的查询</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//1.1准备SQL语句</span><br><span class="hljs-keyword">let</span> strSql = <span class="hljs-string">`select * from h2103`</span>;<br>conn.query(strSql, [], <span class="hljs-function">(<span class="hljs-params">error, results</span>) =&gt;</span> &#123;<br>    <span class="hljs-comment">//1.2这里就是执行完SQL语句以后的结果 ，我们要判断是否执行成功</span><br>    <span class="hljs-keyword">if</span>(error)&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行失败&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(error);<br>    &#125;<br>    <span class="hljs-keyword">else</span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行成功&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(results);<br>    &#125;<br>    conn.end();<br>&#125;);<br></code></pre></td></tr></table></figure>

<h4 id="分析查询结果"><a href="#分析查询结果" class="headerlink" title="分析查询结果"></a>分析查询结果</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs javascript">[<br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;韩军&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;男&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;看书&#x27;</span> &#125;,  <br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;贺涛&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;女&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;看书&#x27;</span> &#125;,  <br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;叶娟&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;女&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;玩游戏&#x27;</span> &#125;,<br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">4</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;于洋&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;女&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;看书&#x27;</span> &#125;,  <br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">5</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;雷秀英&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;女&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;睡觉&#x27;</span> &#125;,<br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">6</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;朱娜&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;女&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;玩游戏&#x27;</span> &#125;,<br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">7</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;叶敏&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;男&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;睡觉&#x27;</span> &#125;,  <br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">8</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;林明&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;女&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;睡觉&#x27;</span> &#125;,  <br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">9</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;陈强&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;男&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;睡觉&#x27;</span> &#125;,  <br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;任芳&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;女&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;看书&#x27;</span> &#125;  <br>]<br></code></pre></td></tr></table></figure>

<p>查询的时候返回的一定是一个数组，这个数组面的每一个对象都是一行数据，用列名做属性名，用当前列的值做属性值</p>
<h4 id="带参数的查询"><a href="#带参数的查询" class="headerlink" title="带参数的查询"></a>带参数的查询</h4><p>刚刚的查询语句里面，我们看到了没有参数的查询，现在如果在查询的时候需要带参数怎么办呢？</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//带参数的SQL语句执行</span><br><span class="hljs-comment">//查询性别为女，爱好是看书的学生</span><br><span class="hljs-comment">//1.1准备要执行的SQL语句，参数使用?来代替</span><br><span class="hljs-keyword">let</span> strSql = <span class="hljs-string">`select * from h2103 where ssex = ? and hobby = ?`</span>;<br><span class="hljs-comment">//1.2执行SQL语句，放参数</span><br>conn.query(strSql, [<span class="hljs-string">&quot;女&quot;</span>, <span class="hljs-string">&quot;看书&quot;</span>], <span class="hljs-function">(<span class="hljs-params">error, results</span>) =&gt;</span> &#123;<br>    <span class="hljs-comment">//1.3SQL语句执行完成</span><br>    <span class="hljs-keyword">if</span> (error) &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行失败&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(error);<br>    &#125;<br>    <span class="hljs-keyword">else</span> &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行成功&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(results);<br>    &#125;<br>    conn.end();<br>&#125;);<br></code></pre></td></tr></table></figure>

<p>执行结果如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript">[<br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;贺涛&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;女&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;看书&#x27;</span> &#125;,<br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">4</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;于洋&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;女&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;看书&#x27;</span> &#125;,<br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">10</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;任芳&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;女&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;看书&#x27;</span> &#125;<br>]<br></code></pre></td></tr></table></figure>

<blockquote>
<p>如果有参数了，直接在SQL语句里面使用<code>?</code>代替，然后在执行SQL语句的时候，在给一个数组，里面放具体的值就可以了</p>
</blockquote>
<h4 id="模糊查询"><a href="#模糊查询" class="headerlink" title="模糊查询"></a>模糊查询</h4><p>在查询的时候如果有模糊查询的要求，我们就需要运行改变SQL语句的执行参数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//模糊查询</span><br><span class="hljs-comment">//查询姓叶的学生</span><br><span class="hljs-comment">//1.1准备要执行的SQL的语句</span><br><span class="hljs-keyword">let</span> strSql = <span class="hljs-string">` select * from h2103 where sname like ? `</span>;<br><span class="hljs-comment">//1.2执行SQL，注意参数</span><br>conn.query(strSql, [<span class="hljs-string">&quot;叶%&quot;</span>], <span class="hljs-function">(<span class="hljs-params">error, results</span>) =&gt;</span> &#123;<br>    <span class="hljs-comment">//1.3SQL执行完毕</span><br>    <span class="hljs-keyword">if</span> (error) &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行失败&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(error);<br>    &#125;<br>    <span class="hljs-keyword">else</span> &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行成功&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(results);<br>    &#125;<br>    conn.end();<br>&#125;);<br></code></pre></td></tr></table></figure>

<p>结果如下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript">[<br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;叶娟&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;女&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;玩游戏&#x27;</span> &#125;,<br>  RowDataPacket &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">7</span>, <span class="hljs-attr">sname</span>: <span class="hljs-string">&#x27;叶敏&#x27;</span>, <span class="hljs-attr">ssex</span>: <span class="hljs-string">&#x27;男&#x27;</span>, <span class="hljs-attr">hobby</span>: <span class="hljs-string">&#x27;睡觉&#x27;</span> &#125;   <br>] <br></code></pre></td></tr></table></figure>

<h4 id="SQL语句的动态拼接"><a href="#SQL语句的动态拼接" class="headerlink" title="SQL语句的动态拼接"></a>SQL语句的动态拼接</h4><blockquote>
<p>这是重点中的重点，慎重对待</p>
</blockquote>
<p><img src="https://pic.imgdb.cn/item/61700c1d2ab3f51d91d18b6b.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211020111321491"></p>
<p>假设页面上面有一个这样的界面需求，后期数据库应该如何执行SQL，这个时候就一定要使用到SQL语句的动态拼接</p>
<p>我们先分析下面的两条SQL语句</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs mysql">select * from h2103 where 1;<br><br>SELECT * from h2103;<br></code></pre></td></tr></table></figure>

<p>这两条SQL语句所执行的效果是一样的，但是有区别 。</p>
<p>在第1条SQL语句的后面我们添加了一<code>where</code>，这样后期即使再有条件，我们也只用直接 添加<code>and 条件</code>，如果是第2条SQL语句拼接就很麻烦 ，因为我如果没有条件就不要where,有条件我就要接where,如果有多个条件有，我后面的条件又不要where,而要and</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//模糊查询</span><br><span class="hljs-comment">//查询姓叶的学生</span><br><span class="hljs-comment">//1.1先定义三个变量，用于模拟页面上面输入框的三个值</span><br><span class="hljs-keyword">let</span> sname = <span class="hljs-string">&quot;&quot;</span>;<br><span class="hljs-keyword">let</span> ssex = <span class="hljs-string">&quot;男&quot;</span>;<br><span class="hljs-keyword">let</span> hobby = <span class="hljs-string">&quot;看书&quot;</span>;<br><span class="hljs-comment">//1.2准备要执行的SQL的基础语句</span><br><span class="hljs-keyword">let</span> strSql = <span class="hljs-string">` select * from h2103 where 1 `</span>;<br><span class="hljs-keyword">let</span> arr = [];<br><span class="hljs-comment">//1.3开始动态拼接</span><br><span class="hljs-keyword">if</span> (sname) &#123;<br>    strSql += <span class="hljs-string">` and sname like ? `</span>;<br>    arr.push(<span class="hljs-string">`%<span class="hljs-subst">$&#123;sname&#125;</span>%`</span>);<br>&#125;<br><span class="hljs-keyword">if</span> (ssex) &#123;<br>    strSql += <span class="hljs-string">` and ssex = ? `</span>;<br>    arr.push(ssex);<br>&#125;<br><span class="hljs-keyword">if</span> (hobby) &#123;<br>    strSql += <span class="hljs-string">` and hobby like ? `</span>;<br>    arr.push(<span class="hljs-string">`%<span class="hljs-subst">$&#123;hobby&#125;</span>%`</span>)<br>&#125;<br><span class="hljs-comment">//1.4执行拼接好的SQL语句</span><br>conn.query(strSql, arr, <span class="hljs-function">(<span class="hljs-params">error, results</span>) =&gt;</span> &#123;<br>    <span class="hljs-keyword">if</span> (error) &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行失败&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(error);<br>    &#125;<br>    <span class="hljs-keyword">else</span> &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行成功&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(results);<br>    &#125;<br>    conn.end();<br>&#125;);<br></code></pre></td></tr></table></figure>

<p>动态查询的操作后期会使用得非常频率</p>
<h4 id="分页查询"><a href="#分页查询" class="headerlink" title="分页查询"></a>分页查询</h4><p>分页查询也是后期必备的一个点，所以现在我们来在上面一章节上面添加分页查询</p>
<p>分页的SQL语句的语法格式如下</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">select 列 from 表 where 条件 limit offset,count<br></code></pre></td></tr></table></figure>

<ul>
<li><code>offset</code>代表你要跳过多少条</li>
<li><code>count</code>取多少条数据</li>
</ul>
<p>如果假设须一个变量<code>pageIndex</code>代表页码，每页显示5条数据 ，则<code>h2103</code>数据表的分页应该公式如下</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mysql">select * from h2103 limit (pageIndex-1)*5,5<br></code></pre></td></tr></table></figure>

<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//分页查询</span><br><span class="hljs-comment">//查询姓叶的学生</span><br><span class="hljs-comment">//1.1先定义三个变量，用于模拟页面上面输入框的三个值</span><br><span class="hljs-keyword">let</span> sname = <span class="hljs-string">&quot;&quot;</span>;<br><span class="hljs-keyword">let</span> ssex = <span class="hljs-string">&quot;男&quot;</span>;<br><span class="hljs-keyword">let</span> hobby = <span class="hljs-string">&quot;&quot;</span>;<br><span class="hljs-keyword">let</span> pageIndex = <span class="hljs-number">1</span>;									<span class="hljs-comment">//关键代码.......</span><br><br><span class="hljs-comment">//1.2准备要执行的SQL的基础语句</span><br><span class="hljs-keyword">let</span> strSql = <span class="hljs-string">` select * from h2103 where 1 `</span>;<br><span class="hljs-keyword">let</span> arr = [];<br><span class="hljs-comment">//1.3开始动态拼接</span><br><span class="hljs-keyword">if</span> (sname) &#123;<br>    strSql += <span class="hljs-string">` and sname like ? `</span>;<br>    arr.push(<span class="hljs-string">`%<span class="hljs-subst">$&#123;sname&#125;</span>%`</span>);<br>&#125;<br><span class="hljs-keyword">if</span> (ssex) &#123;<br>    strSql += <span class="hljs-string">` and ssex = ? `</span>;<br>    arr.push(ssex);<br>&#125;<br><span class="hljs-keyword">if</span> (hobby) &#123;<br>    strSql += <span class="hljs-string">` and hobby like ? `</span>;<br>    arr.push(<span class="hljs-string">`%<span class="hljs-subst">$&#123;hobby&#125;</span>%`</span>)<br>&#125;<br><br><span class="hljs-comment">//拼接要分页条件</span><br>strSql += <span class="hljs-string">` limit <span class="hljs-subst">$&#123;(pageIndex - <span class="hljs-number">1</span>) * <span class="hljs-number">5</span>&#125;</span>,5 `</span>;          <span class="hljs-comment">//关键代码.......</span><br><br><span class="hljs-comment">//1.4执行拼接好的SQL语句</span><br>conn.query(strSql, arr, <span class="hljs-function">(<span class="hljs-params">error, results</span>) =&gt;</span> &#123;<br>    <span class="hljs-keyword">if</span> (error) &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行失败&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(error);<br>    &#125;<br>    <span class="hljs-keyword">else</span> &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;数据库SQL语句执行成功&quot;</span>);<br>        <span class="hljs-built_in">console</span>.log(results);<br>    &#125;<br>    conn.end();<br>&#125;);<br></code></pre></td></tr></table></figure>

<h3 id="多SQL执行"><a href="#多SQL执行" class="headerlink" title="多SQL执行"></a>多SQL执行</h3><blockquote>
<p>待讲</p>
</blockquote>
<hr>
<h3 id="数据库操作的封装过程"><a href="#数据库操作的封装过程" class="headerlink" title="数据库操作的封装过程"></a>数据库操作的封装过程</h3><p>在之前的操作操作里面，我们来分析一下问题</p>
<p><img src="https://pic.imgdb.cn/item/61700c3d2ab3f51d91d1aa3f.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211020120003952"></p>
<p>上面图就是我们之前的操作，我们可以看到每一个文件都在与我的数据进行耦合，这样是不行的，也不规范，这个时候我们的代码应该变成下面的这种方式开发</p>
<p><img src="https://pic.imgdb.cn/item/61700c572ab3f51d91d1c018.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211020120042081"></p>
<p>这个时候上面的图就是实现了高类聚低耦合的特点，所以我们现在要按照这一种开发思路来完成项目的开发</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@description </span>专门用于操作数据库的文件</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@author </span>杨标</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@version </span>1.0</span><br><span class="hljs-comment"> */</span><br><br><span class="hljs-keyword">const</span> mysql = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;mysql&quot;</span>);<br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DBUtils</span> </span>&#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@description </span>获取数据库连接</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@returns <span class="hljs-type">&#123;mysql.Connection&#125;</span></span></span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-function"><span class="hljs-title">getConn</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> conn = mysql.createConnection(&#123;<br>            <span class="hljs-attr">host</span>: <span class="hljs-string">&quot;192.168.1.254&quot;</span>,<br>            <span class="hljs-attr">port</span>: <span class="hljs-number">3306</span>,<br>            <span class="hljs-attr">user</span>: <span class="hljs-string">&quot;dev_h2103&quot;</span>,<br>            <span class="hljs-attr">password</span>: <span class="hljs-string">&quot;123456&quot;</span>,<br>            <span class="hljs-attr">database</span>: <span class="hljs-string">&quot;test1018&quot;</span><br>        &#125;);<br>        <span class="hljs-keyword">return</span> conn;<br>    &#125;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@description </span>执行一条SQL语句返回结果</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param <span class="hljs-type">&#123;string&#125;</span> </span>strSql 要执行的SQL语句 </span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param <span class="hljs-type">&#123;Array&#125;</span> </span>params 执行SQL语句所需要的参数 </span><br><span class="hljs-comment">     * <span class="hljs-doctag">@returns <span class="hljs-type">&#123;Promise&lt;Array&gt;|Promise&lt;mysql.OkPacket&gt;&#125;</span> </span>返回数据库执行的承诺</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-function"><span class="hljs-title">executeSql</span>(<span class="hljs-params">strSql, params = []</span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> p = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> &#123;<br>            <span class="hljs-keyword">let</span> conn = <span class="hljs-built_in">this</span>.getConn();<br>            conn.connect();<br>            conn.query(strSql, params, <span class="hljs-function">(<span class="hljs-params">error, results</span>) =&gt;</span> &#123;<br>                <span class="hljs-keyword">if</span> (error) &#123;<br>                    reject(error);<br>                &#125;<br>                <span class="hljs-keyword">else</span> &#123;<br>                    resolve(results);<br>                &#125;<br>                conn.end();<br>            &#125;);<br>        &#125;);<br>        <span class="hljs-keyword">return</span> p;<br>    &#125;<br>&#125;<br><span class="hljs-built_in">module</span>.exports = DBUtils;<br></code></pre></td></tr></table></figure>

<p>上面的代码就是一个<code>DBUtils</code>操作库的一个封装过程，我们使用了<code>class</code>创建了构造函数，使用了<code>Proimise</code>来处理异步，使用函数的默认参数技术</p>
<p><strong>测试一下封装的代码</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> queryData = <span class="hljs-keyword">async</span> () =&gt; &#123;<br>    <span class="hljs-comment">//查询性别为女的数据</span><br>    <span class="hljs-comment">//1.1准备要执行的SQL语句</span><br>    <span class="hljs-keyword">let</span> strSql = <span class="hljs-string">` select * from h2103 where ssex = ? `</span>;<br>    <span class="hljs-comment">//1.2创建数据库的执行对象</span><br>    <span class="hljs-keyword">let</span> db = <span class="hljs-keyword">new</span> DBUtils();<br>    <span class="hljs-comment">//1.3执行SQL语句，是一个异步的Promise，所以await一下</span><br>    <span class="hljs-keyword">let</span> results = <span class="hljs-keyword">await</span> db.executeSql(strSql, [<span class="hljs-string">&quot;女&quot;</span>]);<br>    <span class="hljs-built_in">console</span>.log(results);<br>&#125;<br>queryData();<br></code></pre></td></tr></table></figure>

<hr>
<h2 id="8-nodejs数据库项目的搭建"><a href="#8-nodejs数据库项目的搭建" class="headerlink" title="8.nodejs数据库项目的搭建"></a>8.nodejs数据库项目的搭建</h2><img src="https://pic.imgdb.cn/item/61700ce12ab3f51d91d23528.png" srcset="/blog/img/loading.gif" lazyload style="zoom:40">

<p>假设我们现在要搭建上面的管理系统项目</p>
<ol>
<li>先通过思维导图划分自己的模块与功能</li>
<li>确定数据库的字段，再创建数据库</li>
<li>通过nodejs搭建</li>
</ol>
<p>一般情况下的数据库都会涉及到表的操作，一个模块可能就是一个表，上面有三个模块，在数据库里面可能就是三个表的操作</p>
<p>但是无论是哪一张表的操作都离不开四个操作“增，删，改，查”。这个时候针对四种操作，我们项目应该如何搭建</p>
<h3 id="初始化项目"><a href="#初始化项目" class="headerlink" title="初始化项目"></a>初始化项目</h3><p>新建文件夹<code>rental_house</code>，然后打开文件夹，调出命令行，输入如下命令</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm init --yes<br></code></pre></td></tr></table></figure>

<p>形成<code>package.json</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs javascript">&#123;<br>    <span class="hljs-string">&quot;name&quot;</span>: <span class="hljs-string">&quot;rental_house&quot;</span>,<br>    <span class="hljs-string">&quot;version&quot;</span>: <span class="hljs-string">&quot;1.0.0&quot;</span>,<br>    <span class="hljs-string">&quot;description&quot;</span>: <span class="hljs-string">&quot;房屋出租系统 &quot;</span>,<br>    <span class="hljs-string">&quot;main&quot;</span>: <span class="hljs-string">&quot;app.js&quot;</span>,<br>    <span class="hljs-string">&quot;scripts&quot;</span>: &#123;<br><br>    &#125;,<br>    <span class="hljs-string">&quot;keywords&quot;</span>: [<br>        <span class="hljs-string">&quot;node.js&quot;</span>, <span class="hljs-string">&quot;房屋出租&quot;</span><br>    ],<br>    <span class="hljs-string">&quot;author&quot;</span>: <span class="hljs-string">&quot;杨标&quot;</span>,<br>    <span class="hljs-string">&quot;license&quot;</span>: <span class="hljs-string">&quot;MIT&quot;</span><br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="安装依赖包"><a href="#安装依赖包" class="headerlink" title="安装依赖包"></a>安装依赖包</h3><p>因为当前只需要完成数据库操作的功能，所以我们只用安装<code>mysql</code>的包即可</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ npm install mysql --save<br></code></pre></td></tr></table></figure>

<h3 id="导入数据库操作的封装对象"><a href="#导入数据库操作的封装对象" class="headerlink" title="导入数据库操作的封装对象"></a>导入数据库操作的封装对象</h3><p>之前的时候我们已经封装了一个文件叫<code>DBUtils.js</code>的文件，将这个文件放在<code>utils</code>的目录</p>
<blockquote>
<p>utils的目录是用于放第三方工具类的，可以放自己的封装的工具，也可以放其它地方获取的工具类方法</p>
</blockquote>
<h3 id="编写服务层"><a href="#编写服务层" class="headerlink" title="编写服务层"></a>编写服务层</h3><blockquote>
<p>服务层就是用于操作数据库的，为前面的程序提供的服务的</p>
<p>前面的程序指的是Controller,也可能是API等一系列操作</p>
</blockquote>
<p>服务层其实就是一个一个对象，这个对象用于操作数据库，这个对象里面编写了很多常用的数据库的操作方法，如新增，修改，删除，查询，分页查询 等一系列方法</p>
<p><img src="https://pic.imgdb.cn/item/61700d792ab3f51d91d2d73e.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211020152257067"></p>
<h4 id="创建service的文件夹"><a href="#创建service的文件夹" class="headerlink" title="创建service的文件夹"></a>创建service的文件夹</h4><p>根据上面的图我们可以得到一点，我们的<code>service</code>应该不只一个文件， 所以我们新建一个文件夹</p>
<h4 id="根据数据库创建service对象"><a href="#根据数据库创建service对象" class="headerlink" title="根据数据库创建service对象"></a>根据数据库创建service对象</h4><p>因为service主要是提供服务，操作数据表，所以正常情况下应该是一个数据表对应一个<code>service</code>文件。现在有三个数据表，所以我们构建三个数据库文件</p>
<ol>
<li><code>admin_info</code>管理员表</li>
<li><code>room_info</code>房间表</li>
<li><code>stu_info</code>学生表</li>
</ol>
<table>
<thead>
<tr>
<th>表名</th>
<th>对象名</th>
<th>备注</th>
</tr>
</thead>
<tbody><tr>
<td>admin_info</td>
<td>AdminInfoService.js</td>
<td></td>
</tr>
<tr>
<td>room_info</td>
<td>RoomInfoService.js</td>
<td></td>
</tr>
<tr>
<td>stu_info</td>
<td>StuInfoService.js</td>
<td></td>
</tr>
</tbody></table>
<h4 id="完成功能里面具体的操作"><a href="#完成功能里面具体的操作" class="headerlink" title="完成功能里面具体的操作"></a>完成功能里面具体的操作</h4><p>假设当前项目经理分配给我的是<code>room_info</code>房间管理的模块，所以我现在只用专注于<code>RoomInfoService.js</code>这个即可</p>
<img src="https://pic.imgdb.cn/item/61700c0b2ab3f51d91d17af3.png" srcset="/blog/img/loading.gif" lazyload style="zoom:40">

<p>当我们拿到上面的原型图，我们的servic肯定要为这一个界面提供服务，那么<code>RoomInfoServcie</code>里面应该如何编写代码呢</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@description </span>RoomInfoServcie 操作room_info数据表</span><br><span class="hljs-comment"> */</span><br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RoomInfoServcie</span> </span>&#123;<br>    <span class="hljs-function"><span class="hljs-title">add</span>(<span class="hljs-params"></span>)</span> &#123;<br><br>    &#125;<br>    <span class="hljs-function"><span class="hljs-title">deleteById</span>(<span class="hljs-params"></span>)</span> &#123;<br><br>    &#125;<br>    <span class="hljs-function"><span class="hljs-title">update</span>(<span class="hljs-params"></span>)</span> &#123;<br><br>    &#125;<br>    <span class="hljs-function"><span class="hljs-title">query</span>(<span class="hljs-params"></span>)</span> &#123;<br><br>    &#125;<br>    <span class="hljs-function"><span class="hljs-title">findById</span>(<span class="hljs-params"></span>)</span> &#123;<br><br>    &#125;<br>&#125;<br><span class="hljs-built_in">module</span>.exports = RoomInfoServcie;<br></code></pre></td></tr></table></figure>

<p>现在强制约束，每个<code>service</code>至少是有这5个方法</p>
<img src="https://pic.imgdb.cn/item/61700dd52ab3f51d91d33918.png" srcset="/blog/img/loading.gif" lazyload style="zoom:40">



<img src="https://pic.imgdb.cn/item/61700e162ab3f51d91d37449.png" srcset="/blog/img/loading.gif" lazyload style="zoom:40">

<p>我们在中间添加了一层<code>BaseService</code>，以期达到项目模块的低耦合的操作</p>
<pre><code class=" mermaid">graph LR
A[RoomInfoServcie.js]--&gt;|继承|B[BaseService.js]--&gt;|继承|C[DBUtils.js]
</code></pre>



<p><strong>DBUtils.js文件</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@description </span>专门用于操作数据库的文件</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@author </span>杨标</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@version </span>1.0</span><br><span class="hljs-comment"> */</span><br><br><span class="hljs-keyword">const</span> mysql = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;mysql&quot;</span>);<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DBUtils</span> </span>&#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@description </span>获取数据库连接</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@returns <span class="hljs-type">&#123;mysql.Connection&#125;</span></span></span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-function"><span class="hljs-title">getConn</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> conn = mysql.createConnection(&#123;<br>            <span class="hljs-attr">host</span>: <span class="hljs-string">&quot;192.168.1.254&quot;</span>,<br>            <span class="hljs-attr">port</span>: <span class="hljs-number">3306</span>,<br>            <span class="hljs-attr">user</span>: <span class="hljs-string">&quot;dev_h2103&quot;</span>,<br>            <span class="hljs-attr">password</span>: <span class="hljs-string">&quot;123456&quot;</span>,<br>            <span class="hljs-attr">database</span>: <span class="hljs-string">&quot;rental_house&quot;</span><br>        &#125;);<br>        <span class="hljs-keyword">return</span> conn;<br>    &#125;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@description </span>执行一条SQL语句返回结果</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param <span class="hljs-type">&#123;string&#125;</span> </span>strSql 要执行的SQL语句 </span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param <span class="hljs-type">&#123;Array&#125;</span> </span>params 执行SQL语句所需要的参数 </span><br><span class="hljs-comment">     * <span class="hljs-doctag">@returns <span class="hljs-type">&#123;Promise&lt;Array&gt;|Promise&lt;mysql.OkPacket&gt;&#125;</span> </span>返回数据库执行的承诺</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-function"><span class="hljs-title">executeSql</span>(<span class="hljs-params">strSql, params = []</span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> p = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> &#123;<br>            <span class="hljs-keyword">let</span> conn = <span class="hljs-built_in">this</span>.getConn();<br>            conn.connect();<br>            conn.query(strSql, params, <span class="hljs-function">(<span class="hljs-params">error, results</span>) =&gt;</span> &#123;<br>                <span class="hljs-keyword">if</span> (error) &#123;<br>                    reject(error);<br>                &#125;<br>                <span class="hljs-keyword">else</span> &#123;<br>                    resolve(results);<br>                &#125;<br>                conn.end();<br>            &#125;);<br>        &#125;);<br>        <span class="hljs-keyword">return</span> p;<br>    &#125;<br>&#125;<br><span class="hljs-built_in">module</span>.exports = DBUtils;<br></code></pre></td></tr></table></figure>

<p><strong>BaseService.js文件</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@description </span>公共的基础服务类，主要用于解耦，并提供基础的方法</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">const</span> DBUtils = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;../utils/DBUtils.js&quot;</span>);<br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BaseService</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">DBUtils</span> </span>&#123;<br><br>&#125;<br><span class="hljs-built_in">module</span>.exports = BaseService;<br></code></pre></td></tr></table></figure>

<p><strong>RoomInfoService.js文件</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@description </span>RoomInfoServcie 操作room_info数据表</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">const</span> BaseService = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;./BaseService.js&quot;</span>);<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RoomInfoServcie</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">BaseService</span> </span>&#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@description </span>新增房间信息</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param <span class="hljs-type">&#123;&#123;room_name, max_count, kt, networknetwork, washroom, room_size&#125;</span></span>&#125; param </span><br><span class="hljs-comment">     * <span class="hljs-doctag">@returns <span class="hljs-type">&#123;Promise&lt;import(&quot;mysql&quot;).OkPacket&gt;&#125;</span> </span>返回数据库操作的结果</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-function"><span class="hljs-title">add</span>(<span class="hljs-params">&#123; room_name, max_count, kt, network, washroom, room_size &#125;</span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> strSql = <span class="hljs-string">`insert into room_info (room_name,max_count,kt,network,washroom,room_size) values (?,?,?,?,?,?) `</span>;<br>        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.executeSql(strSql, [room_name, max_count, kt, network, washroom, room_size]);<br>    &#125;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@description </span>根据id删除房间信息</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param <span class="hljs-type">&#123;number&#125;</span> </span>id 要删除项的主键id </span><br><span class="hljs-comment">     * <span class="hljs-doctag">@returns <span class="hljs-type">&#123;Promise&lt;boolean&gt;&#125;</span> </span>true代表删除成功,false代表删了作制作</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-title">deleteById</span>(<span class="hljs-params">id</span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> strSql = <span class="hljs-string">` delete from room_info where id = ? `</span>;<br>        <span class="hljs-keyword">let</span> results = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.executeSql(strSql, [id]);<br>        <span class="hljs-keyword">return</span> results.affectedRows &gt; <span class="hljs-number">0</span> ? <span class="hljs-literal">true</span> : <span class="hljs-literal">false</span>;<br>    &#125;<br>    <span class="hljs-function"><span class="hljs-title">update</span>(<span class="hljs-params"></span>)</span> &#123;<br><br>    &#125;<br>    <span class="hljs-function"><span class="hljs-title">query</span>(<span class="hljs-params"></span>)</span> &#123;<br><br>    &#125;<br>    <span class="hljs-function"><span class="hljs-title">findById</span>(<span class="hljs-params"></span>)</span> &#123;<br><br>    &#125;<br>&#125;<br><br><span class="hljs-built_in">module</span>.exports = RoomInfoServcie;<br></code></pre></td></tr></table></figure>

<h3 id="BaseService的功能重构"><a href="#BaseService的功能重构" class="headerlink" title="BaseService的功能重构"></a>BaseService的功能重构</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@description </span>公共的基础服务类，主要用于解耦，并提供基础的方法</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">const</span> DBUtils = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;../utils/DBUtils.js&quot;</span>);<br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BaseService</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">DBUtils</span> </span>&#123;<br>    <span class="hljs-function"><span class="hljs-title">constructor</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-built_in">super</span>();<br>        <span class="hljs-built_in">this</span>.tableMap = &#123;<br>            <span class="hljs-attr">admin_info</span>: <span class="hljs-string">&quot;admin_info&quot;</span>,<br>            <span class="hljs-attr">room_info</span>: <span class="hljs-string">&quot;room_info&quot;</span>,<br>            <span class="hljs-attr">stu_info</span>: <span class="hljs-string">&quot;stu_info&quot;</span><br>        &#125;;<br>        <span class="hljs-built_in">this</span>.currentTableName = <span class="hljs-string">&quot;&quot;</span>;<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@description </span>根据一个主键去删除</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param <span class="hljs-type">&#123;number&#125;</span> </span>id  </span><br><span class="hljs-comment">     * <span class="hljs-doctag">@returns <span class="hljs-type">&#123;Promise&lt;boolean&gt;&#125;</span> </span>true代表删除成功，false代表删除失败</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-title">deleteById</span>(<span class="hljs-params">id</span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> strSql = <span class="hljs-string">` delete from <span class="hljs-subst">$&#123;<span class="hljs-built_in">this</span>.currentTableName&#125;</span> where id = ? `</span>;<br>        <span class="hljs-keyword">let</span> results = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.executeSql(strSql, [id]);<br>        <span class="hljs-keyword">return</span> results.affectedRows &gt; <span class="hljs-number">0</span> ? <span class="hljs-literal">true</span> : <span class="hljs-literal">false</span>;<br>    &#125;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@description </span>根据主键id查询信息</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param <span class="hljs-type">&#123;number&#125;</span> </span>id 查询的主键id </span><br><span class="hljs-comment">     * <span class="hljs-doctag">@returns <span class="hljs-type">&#123;Promise&lt;object&gt;&#125;</span> </span>数据库查询的结果</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-title">findById</span>(<span class="hljs-params">id</span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> strSql = <span class="hljs-string">` select * from <span class="hljs-subst">$&#123;<span class="hljs-built_in">this</span>.currentTableName&#125;</span> where id = ? `</span>;<br>        <span class="hljs-keyword">let</span> results = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.executeSql(strSql, [id]);<br>        <span class="hljs-keyword">return</span> results[<span class="hljs-number">0</span>];<br>    &#125;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@description </span>查询所有数据</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@returns <span class="hljs-type">&#123;Promise&lt;[]&gt;&#125;</span> </span>返回数据库查询的结果</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-function"><span class="hljs-title">getAllList</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> strSql = <span class="hljs-string">` select * from <span class="hljs-subst">$&#123;<span class="hljs-built_in">this</span>.currentTableName&#125;</span> `</span>;<br>        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.executeSql(strSql);<br>    &#125;<br>&#125;<br><br><br><span class="hljs-built_in">module</span>.exports = BaseService;<br></code></pre></td></tr></table></figure>

<p>在上面的代码里面，为了更好的实现与数据库的解耦关系，我们在当前的<code>BaseService</code>里面创建了一个<code>tableMap</code>对象，用于映射数据库的表，同时提取出了3个公共的方法</p>
<p><strong>StuInfoService.js</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@description </span>StuInfoServcie 操作stu_info数据表</span><br><span class="hljs-comment"> */</span><br><br><span class="hljs-keyword">const</span> BaseService = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;./BaseService.js&quot;</span>);<br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StuInfoService</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">BaseService</span> </span>&#123;<br>    <span class="hljs-function"><span class="hljs-title">constructor</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-built_in">super</span>();<br>        <span class="hljs-built_in">this</span>.currentTableName = <span class="hljs-built_in">this</span>.tableMap.stu_info;<br>    &#125;<br>&#125;<br><br><span class="hljs-built_in">module</span>.exports = StuInfoService;<br></code></pre></td></tr></table></figure>

<pre><code class=" mermaid">classDiagram
class RoomInfoService&#123;
    &lt;&lt;service&gt;&gt;
    query()
    update()
&#125;
class BaseService&#123;
    &lt;&lt;service&gt;&gt;
    findById(id)
    deleteById(id)
    getAllList()
    tableMap
    currentTableName
&#125;
RoomInfoService--&gt;BaseService:extends
class DBUtils &#123;
	&lt;&lt;数据库操作&gt;&gt;
	getConn()
	executeSql(strSql,params)
&#125;
BaseService--&gt;DBUtils:extends
</code></pre>



<hr>
<h3 id="简单工厂模式"><a href="#简单工厂模式" class="headerlink" title="简单工厂模式"></a>简单工厂模式</h3><p>我们后期在测试这些功能（或者使用这些service）的时候我们又发现一个问题，如果当前的某一个文件同时使用了多个<code>service</code>这个每个文件都需要导入一次，很麻烦</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 测试基础的公共方法</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">const</span> AdminInfoService = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;../services/AdminInfoService.js&quot;</span>);<br><span class="hljs-keyword">const</span> RoomInfoService = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;../services/RoomInfoService.js&quot;</span>);<br><span class="hljs-keyword">const</span> StuInfoService = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;../services/StuInfoService.js&quot;</span>);<br><span class="hljs-comment">//每个文件都要导这么多的service，怎么办呢</span><br></code></pre></td></tr></table></figure>

<p>同时导入的文件每次都要<code>new</code> 一下才能使用，这个时候就很有问题</p>
<p><img src="https://pic.imgdb.cn/item/61714b2e2ab3f51d91bf2ea3.png" srcset="/blog/img/loading.gif" lazyload alt="image-20211021161230328"></p>
<p>现象我为了实现与项目前端面结合，我们需要降低这个耦合性，所以我们会生产一个对象叫工厂对象，这个工厂专门用于生成所有的<code>Service</code>，最后只要让这一个文件与所有的页面实现耦合就可以了</p>
<p><strong>ServiceFactory.js文件</strong></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 工厂模式</span><br><span class="hljs-comment"> */</span><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ServiceFactory</span> </span>&#123;<br>    <span class="hljs-function"><span class="hljs-title">constructor</span>(<span class="hljs-params"></span>)</span>&#123;<br>        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">&quot;当前对象不需要new&quot;</span>);<br>    &#125;<br>    <span class="hljs-keyword">static</span> <span class="hljs-function"><span class="hljs-title">createAdminInfoService</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> AdminInfoService = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;../services/AdminInfoService.js&quot;</span>);<br>        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> AdminInfoService();<br>    &#125;<br>    <span class="hljs-keyword">static</span> <span class="hljs-function"><span class="hljs-title">createRoomInfoService</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> RoomInfoService = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;../services/RoomInfoService.js&quot;</span>)<br>        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> RoomInfoService();<br>    &#125;<br>    <span class="hljs-keyword">static</span> <span class="hljs-function"><span class="hljs-title">createStuInfoService</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> StuInfoService = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;../services/StuInfoService.js&quot;</span>)<br>        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> StuInfoService();<br>    &#125;<br>&#125;<br><span class="hljs-built_in">module</span>.exports = ServiceFactory;<br></code></pre></td></tr></table></figure>

<p>上面是我们手动创建的一个工厂，这样后期我们要使用Service统一使用这个文件就可以了</p>
<p>当我们再去使用这个Service的时候就可以像这面这种试使用了</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 测试基础的公共方法</span><br><span class="hljs-comment"> */</span><br><br><span class="hljs-keyword">const</span> ServiceFactory = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;../factory/ServiceFactory.js&quot;</span>);<br><span class="hljs-comment">//测试admin_info 获取所有数据</span><br><span class="hljs-comment">/*</span><br><span class="hljs-comment">const getAdminInfoAllData = async () =&gt; &#123;</span><br><span class="hljs-comment">    let results = await ServiceFactory.createAdminInfoService().getAllList();</span><br><span class="hljs-comment">    console.log(results);</span><br><span class="hljs-comment">&#125;</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">const getRoomInfo = async () =&gt; &#123; </span><br><span class="hljs-comment">    let results = await ServiceFactory.createRoomInfoService().findById(2);</span><br><span class="hljs-comment">    console.log(results);</span><br><span class="hljs-comment">&#125;</span><br><span class="hljs-comment">getRoomInfo();</span><br><span class="hljs-comment">*/</span><br><br>ServiceFactory.createAdminInfoService().getAllList().then(<span class="hljs-function"><span class="hljs-params">results</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(results));<br>ServiceFactory.createRoomInfoService().findById(<span class="hljs-number">2</span>).then(<span class="hljs-function"><span class="hljs-params">results</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(results));<br></code></pre></td></tr></table></figure>

<p>这个时候我们可以看到所有的Service都是由当前的工厂<code>ServiceFactory</code>产生</p>
<blockquote>
<ol>
<li><code>ServcieFactory</code>里面所有的方法都是静态方法，不需要new就可以使用</li>
</ol>
</blockquote>
<p>之前的工厂模式代码里面，我们使用了<code>class</code>的静态方法，现在还有一种情况可以使用下面的代码【标哥推荐】</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 工厂模式</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">const</span> ServiceFactory = <span class="hljs-built_in">Object</span>.freeze(&#123;<br>    <span class="hljs-keyword">get</span> <span class="hljs-title">adminInfoService</span>() &#123;<br>        <span class="hljs-keyword">let</span> AdminInfoService = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;../services/AdminInfoService.js&quot;</span>);<br>        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> AdminInfoService();<br>    &#125;,<br>    <span class="hljs-keyword">get</span> <span class="hljs-title">roomInfoService</span>() &#123;<br>        <span class="hljs-keyword">let</span> RoomInfoService = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;../services/RoomInfoService.js&quot;</span>)<br>        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> RoomInfoService();<br>    &#125;,<br>    <span class="hljs-keyword">get</span> <span class="hljs-title">stuInfoService</span>() &#123;<br>        <span class="hljs-keyword">let</span> StuInfoService = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;../services/StuInfoService.js&quot;</span>)<br>        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> StuInfoService();<br>    &#125;<br>&#125;);<br><span class="hljs-built_in">module</span>.exports = ServiceFactory;<br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 1.访问器属性get</span><br><span class="hljs-comment"> * 2.使用对象的冻结来保护对象的内部</span><br><span class="hljs-comment"> */</span><br></code></pre></td></tr></table></figure>

<h3 id="抽象工厂模式"><a href="#抽象工厂模式" class="headerlink" title="抽象工厂模式"></a>抽象工厂模式</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 抽象工厂模式</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;path&quot;</span>);<br><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;fs&quot;</span>);<br><br><span class="hljs-comment">//自定义类型可以生成代码提示，commonjs没有代码提示</span><br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@typedef <span class="hljs-variable">AbstractServiceFactory</span></span></span><br><span class="hljs-comment"> * <span class="hljs-doctag">@property <span class="hljs-type">&#123;import (&quot;../Services/AdminInfoService.js&quot;)&#125;</span> <span class="hljs-variable">adminInfoService</span></span></span><br><span class="hljs-comment"> * <span class="hljs-doctag">@property <span class="hljs-type">&#123;import (&quot;../Services/RoomInfoService.js&quot;)&#125;</span> <span class="hljs-variable">roomInfoService</span></span></span><br><span class="hljs-comment"> * <span class="hljs-doctag">@property <span class="hljs-type">&#123;import (&quot;../Services/StuInfoService.js&quot;)&#125;</span> <span class="hljs-variable">stuInfoService</span></span></span><br><span class="hljs-comment"> */</span><br><br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@description </span>抽象的工厂类且可以自动扫描并创建</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@type <span class="hljs-type">&#123;AbstractServiceFactory&#125;</span></span></span><br><span class="hljs-comment"> */</span><br><br><span class="hljs-keyword">const</span> ServiceFactory = (<span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-keyword">let</span> obj = &#123;&#125;<br>    <span class="hljs-keyword">let</span> arr = fs.readdirSync(path.join(__dirname, <span class="hljs-string">&quot;../services&quot;</span>));<br>    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> item <span class="hljs-keyword">of</span> arr) &#123;<br>        <span class="hljs-comment">//1.1构建属性名</span><br>        <span class="hljs-keyword">let</span> propertyName = item.replace(<span class="hljs-string">&quot;.js&quot;</span>, <span class="hljs-string">&quot;&quot;</span>).replace(<span class="hljs-regexp">/^[A-Z]/</span>, <span class="hljs-function"><span class="hljs-params">p</span> =&gt;</span> p.toLowerCase());<br>        <span class="hljs-comment">//1.2导入文件，反射对象</span><br>  		<span class="hljs-keyword">let</span> fnc=<span class="hljs-built_in">require</span>(path.join(__dirname,<span class="hljs-string">&quot;../Services&quot;</span>,item));<br>        <span class="hljs-keyword">if</span>(<span class="hljs-keyword">typeof</span> fnc ===<span class="hljs-string">&quot;function&quot;</span>)&#123;   <span class="hljs-comment">//文件可能返回的不是函数</span><br>            obj[propertyName]=<span class="hljs-built_in">Reflect</span>.construct(fnc,[]);      <span class="hljs-comment">//自动导入Services中的所有js文件使用反射方法 new出对象</span><br>        &#125;<br>    &#125;<br>    <span class="hljs-keyword">return</span> obj;<br>&#125;)();<br><br><br><span class="hljs-built_in">module</span>.exports = ServiceFactory;<br></code></pre></td></tr></table></figure>

<blockquote>
<p>在当前的抽象工厂模式里面，我们直接读取了<code>services</code>文件夹的路径，然后找到文件 ，动态创建对象，动态导入文件，然后反射这个构造函数得到对象</p>
<p>后期如果有新的数据表，我们只需要在<code>services</code>文件夹下面创建新的XXXService.js文件就可以了，系统会自动的帮我们反射出来</p>
</blockquote>

            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/blog/categories/%E5%90%8E%E7%AB%AF%E7%AC%94%E8%AE%B0/">后端笔记</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/blog/tags/JavaScript/">JavaScript</a>
                    
                      <a class="hover-with-bg" href="/blog/tags/ES6/">ES6</a>
                    
                      <a class="hover-with-bg" href="/blog/tags/MySQL/">MySQL</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">
                  
                    本博客所有文章除特别声明外，均采用 <a target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！
                  
                </p>
              
              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/blog/2021/11/17/Sass-css%E6%8B%93%E5%B1%95%E8%AF%AD%E8%A8%80/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">Sass-css拓展语言</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/blog/2021/11/16/MySQL%E7%AC%94%E8%AE%B0/">
                        <span class="hidden-mobile">MySQL笔记</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    

    
      <a id="scroll-top-button" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
  </main>

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
     <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
  </div>
  

  

  
</footer>


  <!-- SCRIPTS -->
  
  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js" ></script>
<script  src="/blog/js/events.js" ></script>
<script  src="/blog/js/plugins.js" ></script>

<!-- Plugins -->


  
    <script  src="/blog/js/img-lazyload.js" ></script>
  



  



  <script  src="https://cdn.jsdelivr.net/npm/tocbot@4.12.3/dist/tocbot.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4.3.1/anchor.min.js" ></script>



  <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js" ></script>



  <script  src="/blog/js/local-search.js" ></script>






  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2.0.12/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
      typing(title)
      
    })(window, document);
  </script>









  <script  src="https://cdn.jsdelivr.net/npm/mermaid@8.10.1/dist/mermaid.min.js" ></script>
  <script>
    if (window.mermaid) {
      mermaid.initialize({"theme":"default"});
    }
  </script>







<!-- 主题的启动项 保持在最底部 -->
<script  src="/blog/js/boot.js" ></script>


</body>
</html>
